Skip to content

Instantly share code, notes, and snippets.

@enerick
Created December 13, 2011 22:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enerick/1474207 to your computer and use it in GitHub Desktop.
Save enerick/1474207 to your computer and use it in GitHub Desktop.
愚直実装版1次元CAくん(状態を配列に収めてインデックスに状態を割り当てるみたいな工夫は一切無い)
let rec print_int_list = function
| [] -> print_newline ()
| x::xs -> print_int x; print_int_list xs;;
(* リストの両端のはみ出しに対応させた拡張nth関数 *)
let nth_ex li = function
| n when n < 0 -> List.nth li (List.length li - 1)
| n when n >= (List.length li) -> List.nth li 0
| n -> List.nth li n;;
(* int listを(int * int * int)のタプルに分ける関数 *)
let partition li =
let rec tmp acc = function
| n when n = (List.length li) -> List.rev acc
| n -> tmp (((nth_ex li (n-1)),(nth_ex li n),(nth_ex li (n+1)))::acc) (n+1)
in tmp [] 0;;
(* 規則の割り当て *)
let filter = function
| (1,1,1) -> 1
| (1,0,1) -> 1
| (1,0,0) -> 1
| (0,1,1) -> 1
| (_,_,_) -> 0;;
(* int list から次の状態のint list を作る *)
let makenext li = List.fold_right (fun x y -> (filter x)::y) (partition li) [];;
(* セルオートマトン本体 *)
let rec ca184 li = function
| 0 -> (print_int_list li)
| x -> (print_int_list li);
ca184 (makenext li) (x-1);;
(* 以下テスト *)
let iof = int_of_float;;
Random.init 149;;
let check n li = List.length (List.filter (fun x -> x=1) li) = (iof (20.*.n));;
let rec makelist n =
let rec tmp li = function
| a when a = 20 ->
let lis = List.map (fun x -> if (x < (iof (n*.10.))) then 1 else 0) li
in if check n lis then lis else makelist n
| a -> tmp ((Random.int 10)::li) (a+1)
in tmp [] 0;;
ca184 (makelist 0.3) 20;;
ca184 (makelist 0.5) 20;;
ca184 (makelist 0.7) 20;;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment