AoC 2015 Day 7
Mix.install([:kino])
defmodule Utils do
def split(line, sep \\ "") do
String.split(line, sep, trim: true)
end
def split_all_lines(text, sep \\ "") do
text
|> String.split("\n", trim: true)
|> Enum.map(&split(&1, sep))
end
def to_numbers(number) when is_binary(number) do
String.to_integer(number)
end
def to_numbers(numbers) when is_list(numbers) do
Enum.map(numbers, &to_numbers/1)
end
def to_matrix(text, sep \\ "") do
text
|> split_all_lines(sep)
|> then(fn data ->
for {row, r} <- Enum.with_index(data), {col, c} <- Enum.with_index(row) do
{{r, c}, col}
end
end)
|> Map.new()
end
end
Setup
import Utils
input = Kino.Input.textarea("Input:")
text = Kino.Input.read(input)
data =
split_all_lines(text, " -> ")
|> Enum.map(fn [l, r] -> {r, l |> String.split() |> List.to_tuple()} end)
|> Enum.into(%{})
defmodule Gates do
def eval({left, "AND", right}, lookup) do
Bitwise.band(get(left, lookup), get(right, lookup))
end
def eval({left, "OR", right}, lookup) do
Bitwise.bor(get(left, lookup), get(right, lookup))
end
def eval({left, "LSHIFT", right}, lookup) do
Bitwise.bsl(get(left, lookup), get(right, lookup))
end
def eval({left, "RSHIFT", right}, lookup) do
Bitwise.bsr(get(left, lookup), get(right, lookup))
end
def eval({"NOT", right}, lookup) do
65536 + Bitwise.bnot(get(right, lookup))
end
def eval({v}, lookup) do
get(v, lookup)
end
def get(target, lookup) do
v =
case Agent.get(lookup, & &1[target]) do
v when is_tuple(v) ->
eval(v, lookup)
nil ->
case target do
v when is_binary(v) -> String.to_integer(v)
v when is_integer(v) -> v
end
v ->
v
end
Agent.update(lookup, &Map.put(&1, target, v))
v
end
end
{:ok, pid} = Agent.start_link(fn -> data end)
P1
a = Gates.get("a", pid)
P2
Agent.update(pid, fn _ -> Map.put(data, "b", a) end)
Gates.get("a", pid)