2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
84
Task/Wireworld/Elixir/wireworld.elixir
Normal file
84
Task/Wireworld/Elixir/wireworld.elixir
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
defmodule Wireworld do
|
||||
@empty " "
|
||||
@head "H"
|
||||
@tail "t"
|
||||
@conductor "."
|
||||
@neighbours (for x<- -1..1, y <- -1..1, do: {x,y}) -- [{0,0}]
|
||||
|
||||
def set_up(string) do
|
||||
lines = String.split(string, "\n", trim: true)
|
||||
grid = Enum.with_index(lines)
|
||||
|> Enum.flat_map(fn {line,i} ->
|
||||
String.codepoints(line)
|
||||
|> Enum.with_index
|
||||
|> Enum.map(fn {char,j} -> {{i, j}, char} end)
|
||||
end)
|
||||
|> Enum.into(Map.new)
|
||||
width = Enum.map(lines, fn line -> String.length(line) end) |> Enum.max
|
||||
height = length(lines)
|
||||
{grid, width, height}
|
||||
end
|
||||
|
||||
# to string
|
||||
defp to_s(grid, width, height) do
|
||||
Enum.map_join(0..height-1, fn i ->
|
||||
Enum.map_join(0..width-1, fn j -> Map.get(grid, {i,j}, @empty) end) <> "\n"
|
||||
end)
|
||||
end
|
||||
|
||||
# transition all cells simultaneously
|
||||
defp transition(grid) do
|
||||
Enum.into(grid, Map.new, fn {{x, y}, state} ->
|
||||
{{x, y}, transition_cell(grid, state, x, y)}
|
||||
end)
|
||||
end
|
||||
|
||||
# how to transition a single cell
|
||||
defp transition_cell(grid, current, x, y) do
|
||||
case current do
|
||||
@empty -> @empty
|
||||
@head -> @tail
|
||||
@tail -> @conductor
|
||||
_ -> if neighbours_with_state(grid, x, y) in 1..2, do: @head, else: @conductor
|
||||
end
|
||||
end
|
||||
|
||||
# given a position in the grid, find the neighbour cells with a particular state
|
||||
def neighbours_with_state(grid, x, y) do
|
||||
Enum.count(@neighbours, fn {dx,dy} -> Map.get(grid, {x+dx, y+dy}) == @head end)
|
||||
end
|
||||
|
||||
# run a simulation up to a limit of transitions, or until a recurring
|
||||
# pattern is found
|
||||
# This will print text to the console
|
||||
def run(string, iterations\\25) do
|
||||
{grid, width, height} = set_up(string)
|
||||
Enum.reduce(0..iterations, {grid, %{}}, fn count,{grd, seen} ->
|
||||
IO.puts "Generation : #{count}"
|
||||
IO.puts to_s(grd, width, height)
|
||||
|
||||
if seen[grd] do
|
||||
IO.puts "I've seen this grid before... after #{count} iterations"
|
||||
exit(:normal)
|
||||
else
|
||||
{transition(grd), Map.put(seen, grd, count)}
|
||||
end
|
||||
end)
|
||||
IO.puts "ran through #{iterations} iterations"
|
||||
end
|
||||
end
|
||||
|
||||
# this is the "2 Clock generators and an XOR gate" example from the wikipedia page
|
||||
text = """
|
||||
......tH
|
||||
. ......
|
||||
...Ht... .
|
||||
....
|
||||
. .....
|
||||
....
|
||||
tH...... .
|
||||
. ......
|
||||
...Ht...
|
||||
"""
|
||||
|
||||
Wireworld.run(text)
|
||||
Loading…
Add table
Add a link
Reference in a new issue