Last active
July 13, 2016 09:33
-
-
Save dehowell/b311759a5dba5dea644fa519735828b7 to your computer and use it in GitHub Desktop.
One-Dimensional Cellular Automaton in Elixir
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
*.beam |
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
defmodule CellularAutomata do | |
@initial [0, 1, 0] | |
def run(generations, rule_number) do | |
rule_fn = rule(rule_number) | |
width = generations * 2 + 1 | |
Stream.iterate(@initial, &(step(&1, rule_fn))) | |
|> Enum.take(generations) | |
|> Enum.map(&(center_pad(&1, width, 0))) | |
|> Enum.each(&print/1) | |
end | |
# Generate a rule function | |
def rule(n) do | |
digits = to_binary(n, 8) | |
rules = Enum.to_list(7..0) | |
|> Enum.map(&(to_binary(&1, 3))) | |
map = Enum.zip(rules, digits) | |
|> Map.new | |
fn ns -> map[ns] end | |
end | |
# Advance the cellular automata one generation. | |
# | |
# The edges will be padded with zeroes to account for the boundary conditions. | |
defp step(field, rule) do | |
Enum.chunk([0, 0] ++ field ++ [0, 0], 3, 1) |> Enum.map(rule) | |
end | |
# Convert an integer into a list of binary digits, left-padded with zeroes. | |
defp to_binary(n, size), do: Integer.digits(n, 2) |> left_pad(size, 0) | |
defp left_pad(list, n, value) when length(list) < n do | |
left_pad([value | list], n, value) | |
end | |
defp left_pad(list, _, _), do: list | |
# This is gross. | |
defp center_pad(list, width, value) when length(list) < width do | |
center_pad([value|list] ++ [value], width, value) | |
end | |
defp center_pad(list, _, _), do: list | |
defp print([0|tail]) do | |
IO.write(" ") | |
print(tail) | |
end | |
defp print([1|tail]) do | |
IO.write("X") | |
print(tail) | |
end | |
defp print([]), do: IO.puts("") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment