トップ
新規
単語検索
ヘルプ
OCamlテクニック/santa
をテンプレートにして作成
開始行:
[[OCamlテクニック/santa]]
* 問題の定義 [#m10796f4]
[[今日の一行:http://karetta.jp/article/blog/oneline/03075...
以下の動作をシミュレートするプログラムを作りたい。
> ねぼすけサンタがいる.休日が開けて,9頭いるトナカイ全...
> 9頭組のトナカイに起こされたら,ハーネスをつけてソリを...
> 3人組のこびとさんたちに起こされたら,会議をひらいて次...
> トナカイ9頭組とこびとさん3人組が同時にサンタが起きる...
* OCamlによる実装例 [#ye3f04e2]
(*
サンタクロース問題の実装例
to compile:
ocamlc -thread unix.cma threads.cma santa.ml
*)
open Event
(* 補助関数 *)
let (@@) f g = f g
let ($) f g x = f (g x)
let delay () =
Thread.delay (Random.float 3.)
let rec loop f =
let _ = f () in loop f
let forever f =
Thread.create loop f
(* トナカイがサンタの部屋に入った事を告げるチャンネル *)
let rch = new_channel ()
(* こびとがサンタの部屋に入った事を告げるチャンネル *)
let ech = new_channel ()
(* サンタにトナカイもしくはこびとが人数分集まったことを...
let sch = new_channel ()
let actor ch n =
for i = 0 to n do
ignore @@ Thread.create (fun () -> delay (); sync @@...
done
let reindeer = actor rch
let elf = actor ech
let santa () =
wrap (receive sch) (function
`Reindeer ->
Printf.printf "santa deliver with reindeer\n";
flush stdout;
reindeer 9
| `Elf ->
Printf.printf "santa confer with elf\n";
flush stdout;
elf 3)
let wait ch n =
for i = 0 to n do
sync @@ receive ch
done
let _ =
Random.self_init ();
let t =
forever (sync $ santa)
in
ignore @@ forever (fun () -> wait rch 9; sync @@ send ...
ignore @@ forever (fun () -> wait ech 3; sync @@ send ...
reindeer 9;
elf 10;
Thread.join t
* ちょっと解説 [#v05db5d2]
サンタ、9頭のトナカイ、10人のこびと、9頭のトナカイを待つ...
トナカイとこびとは、それぞれランダム時間待つと、チャンネ...
トナカイの仲介人は、9頭集まるとサンタにトナカイが集まった...
こびとの仲介人は、3人集まるとサンタにこびとが集まったこと...
サンタは、トナカイかこびとが集まると指定の仕事をして、ま...
イベントを集約してまた別のイベントを発生させるという、簡...
トナカイとこびとにそれぞれ名前を付けてもよかったのですが、
問題に要請がなかったのでやめました。
名前のリストを持って回るだけで、本質的な仕組みは変わりま...
コメント抜いて53行です。ちょっと多いか...。
終了行:
[[OCamlテクニック/santa]]
* 問題の定義 [#m10796f4]
[[今日の一行:http://karetta.jp/article/blog/oneline/03075...
以下の動作をシミュレートするプログラムを作りたい。
> ねぼすけサンタがいる.休日が開けて,9頭いるトナカイ全...
> 9頭組のトナカイに起こされたら,ハーネスをつけてソリを...
> 3人組のこびとさんたちに起こされたら,会議をひらいて次...
> トナカイ9頭組とこびとさん3人組が同時にサンタが起きる...
* OCamlによる実装例 [#ye3f04e2]
(*
サンタクロース問題の実装例
to compile:
ocamlc -thread unix.cma threads.cma santa.ml
*)
open Event
(* 補助関数 *)
let (@@) f g = f g
let ($) f g x = f (g x)
let delay () =
Thread.delay (Random.float 3.)
let rec loop f =
let _ = f () in loop f
let forever f =
Thread.create loop f
(* トナカイがサンタの部屋に入った事を告げるチャンネル *)
let rch = new_channel ()
(* こびとがサンタの部屋に入った事を告げるチャンネル *)
let ech = new_channel ()
(* サンタにトナカイもしくはこびとが人数分集まったことを...
let sch = new_channel ()
let actor ch n =
for i = 0 to n do
ignore @@ Thread.create (fun () -> delay (); sync @@...
done
let reindeer = actor rch
let elf = actor ech
let santa () =
wrap (receive sch) (function
`Reindeer ->
Printf.printf "santa deliver with reindeer\n";
flush stdout;
reindeer 9
| `Elf ->
Printf.printf "santa confer with elf\n";
flush stdout;
elf 3)
let wait ch n =
for i = 0 to n do
sync @@ receive ch
done
let _ =
Random.self_init ();
let t =
forever (sync $ santa)
in
ignore @@ forever (fun () -> wait rch 9; sync @@ send ...
ignore @@ forever (fun () -> wait ech 3; sync @@ send ...
reindeer 9;
elf 10;
Thread.join t
* ちょっと解説 [#v05db5d2]
サンタ、9頭のトナカイ、10人のこびと、9頭のトナカイを待つ...
トナカイとこびとは、それぞれランダム時間待つと、チャンネ...
トナカイの仲介人は、9頭集まるとサンタにトナカイが集まった...
こびとの仲介人は、3人集まるとサンタにこびとが集まったこと...
サンタは、トナカイかこびとが集まると指定の仕事をして、ま...
イベントを集約してまた別のイベントを発生させるという、簡...
トナカイとこびとにそれぞれ名前を付けてもよかったのですが、
問題に要請がなかったのでやめました。
名前のリストを持って回るだけで、本質的な仕組みは変わりま...
コメント抜いて53行です。ちょっと多いか...。
ページ名: