Skip to content

Instantly share code, notes, and snippets.

@styx
Forked from avdi/gol.exs
Created December 20, 2013 13:14
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 styx/8054603 to your computer and use it in GitHub Desktop.
Save styx/8054603 to your computer and use it in GitHub Desktop.
defmodule Life do
def run(board) when is_binary(board) do
board |> parse_board |> run
end
def run(board) do
IO.write("\e[H\e[2J")
Life.print_board board
:timer.sleep 1000
board = next_board(board)
run(board)
end
def parse_board(board) do
rows = Regex.scan(%r/^[.o]+$/m, board)
Enum.map rows, String.graphemes(&1)
end
def print_board(board) do
Enum.each board, fn row ->
IO.puts(Enum.join(row))
end
end
def next_board(board) do
Enum.map board, fn row, y ->
Enum.map row, fn _, x ->
next_state(board, x, y)
end
end
end
def next_state(board, x, y) do
cell = cell_at(board, x, y)
live_count = live_neighbors(board, x, y)
next_state(cell, live_count)
end
def next_state("o", live_count) when live_count in 2..3, do: "o"
def next_state("o", _), do: "."
def next_state(".", live_count) when live_count === 3, do: "o"
def next_state(".", _) do: "."
def cell_at(_, x, y) when (x < 0 or y < 0), do: "."
def cell_at(board, x, y) do
case Enum.at(board, y) do
nil -> "."
row -> Enum.at(row, x, ".")
end
end
def live_neighbors(board, x, y) do
Enum.count(neighbors(board, x, y), &1 === "o")
end
def neighbors(board, x, y) do
coords = neighbor_coords(x, y)
Enum.map coords, fn [x,y] -> cell_at(board, x,y) end
end
def neighbor_coords(x, y) do
[[x-1, y-1], [x, y-1], [x+1, y-1],
[x-1, y], [x+1, y],
[x-1, y+1], [x, y+1], [x+1, y+1]]
end
end
board = """
.o......
..o.....
ooo.....
........
........
........
........
........
"""
Life.run(board)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment