Last active
March 26, 2016 14:03
-
-
Save ninegrid/11315448 to your computer and use it in GitHub Desktop.
1D 2-color cellular automata in F#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type cell = A | B | |
type 'cell U = U of 'cell LazyList * 'cell * LazyList<'cell> | |
module Universe = | |
open LazyList | |
let U left focus right = U (left, focus, right) | |
let initial () = U (repeat A) B (repeat A) | |
let shiftRight = fun (U (left,focus,Cons(focus',right))) -> U (cons focus left) focus' right | |
let shiftLeft = fun (U (Cons(focus',left),focus,right)) -> U left focus' (cons focus right) | |
let left (U(l,_,_)) = l | |
let focus (U(_,f,_)) = f | |
let right (U(_,_,r)) = r | |
let fmap f (U(left,focus,right)) = U (map f left) (f focus) (map f right) | |
let invert = fmap (function A -> B | B -> A) | |
let iterate f (a : 'a U) = unfold (fun a -> Some(a, f a)) a | |
let cojoin (a : 'a U) = U (tail <| iterate shiftLeft a) a (tail <| iterate shiftRight a) | |
let coreturn = focus | |
let inline (=>>) f x = fmap f (cojoin x) | |
module Rules = | |
open Universe | |
open LazyList | |
let u = initial () | |
let cou = invert <| u | |
let rule_gen_2c1d (n : byte) (U (left,focus,right)) = | |
let x = | |
new System.Collections.BitArray([|n|]) | |
|> Seq.cast<bool> | |
|> Seq.map (function true -> B | false -> A) | |
|> Seq.toArray | |
match head left, focus, head right with | |
| B,B,B -> x.[7] | |
| B,B,A -> x.[6] | |
| B,A,B -> x.[5] | |
| B,A,A -> x.[4] | |
| A,B,B -> x.[3] | |
| A,B,A -> x.[2] | |
| A,A,B -> x.[1] | |
| A,A,A -> x.[0] | |
module IO = | |
open LazyList | |
open Universe | |
open Rules | |
module Console = | |
open System | |
let write (s : string) = System.Console.Write s | |
let newline () = System.Console.WriteLine("") | |
let printc = function | |
| A -> write " " | |
| B -> write "█" | |
let printu (U(l,f,r)) n = | |
newline () | |
List.iter (printc) (List.rev (toList <| take n l)) | |
printc f | |
iter (printc) (take n r) | |
let drawu rule_f rule_n length height u = | |
newline () | |
iter (flip printu ((length / 2) - 1)) <| (take height <| iterate ((=>>) <| rule_f rule_n) u) | |
newline () | |
let multiverse_2c1d length height = | |
let rec aux n = | |
match n with | |
| n when n < 255uy -> System.Console.WriteLine (); | |
System.Console.WriteLine (); | |
System.Console.WriteLine ("Rule: {0}", n) | |
drawu rule_gen_2c1d n length height u; | |
aux (n + 1uy) | |
| _ -> System.Console.WriteLine ("Rule: {0}", n) | |
drawu rule_gen_2c1d n length height u; | |
() | |
aux 0uy |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment