solve 2015 day 7
This commit is contained in:
parent
9d4492391c
commit
7426db6489
1 changed files with 145 additions and 1 deletions
|
@ -2,13 +2,157 @@ import AOC
|
||||||
|
|
||||||
aoc 2015, 7 do
|
aoc 2015, 7 do
|
||||||
import NimbleParsec
|
import NimbleParsec
|
||||||
|
use Bitwise
|
||||||
|
|
||||||
def parse_inst(line) do
|
defparsec(
|
||||||
|
:wire_label,
|
||||||
|
ascii_string([?a..?z], min: 1)
|
||||||
|
|> unwrap_and_tag(:wire)
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:connects_to,
|
||||||
|
ignore(string(" -> "))
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:signal,
|
||||||
|
integer(min: 1)
|
||||||
|
|> unwrap_and_tag(:signal)
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:input,
|
||||||
|
choice([
|
||||||
|
parsec(:signal),
|
||||||
|
parsec(:wire_label)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:and,
|
||||||
|
parsec(:input)
|
||||||
|
|> ignore(string(" AND "))
|
||||||
|
|> parsec(:input)
|
||||||
|
|> tag(:and)
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:or,
|
||||||
|
parsec(:input)
|
||||||
|
|> ignore(string(" OR "))
|
||||||
|
|> parsec(:input)
|
||||||
|
|> tag(:or)
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:lshift,
|
||||||
|
parsec(:wire_label)
|
||||||
|
|> ignore(string(" LSHIFT "))
|
||||||
|
|> integer(min: 1)
|
||||||
|
|> tag(:lshift)
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:rshift,
|
||||||
|
parsec(:wire_label)
|
||||||
|
|> ignore(string(" RSHIFT "))
|
||||||
|
|> integer(min: 1)
|
||||||
|
|> tag(:rshift)
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:not,
|
||||||
|
ignore(string("NOT "))
|
||||||
|
|> parsec(:wire_label)
|
||||||
|
|> tag(:not)
|
||||||
|
)
|
||||||
|
|
||||||
|
defparsec(
|
||||||
|
:instruction_parsec,
|
||||||
|
choice([
|
||||||
|
parsec(:and),
|
||||||
|
parsec(:or),
|
||||||
|
parsec(:lshift),
|
||||||
|
parsec(:rshift),
|
||||||
|
parsec(:not),
|
||||||
|
parsec(:input)
|
||||||
|
])
|
||||||
|
|> parsec(:connects_to)
|
||||||
|
|> parsec(:wire_label)
|
||||||
|
)
|
||||||
|
|
||||||
|
def unwrap_parsec_result({:ok, [{tag, attrs}, {:wire, assign}], _, _, _, _}) do
|
||||||
|
attrs = List.wrap(attrs)
|
||||||
|
{assign, List.to_tuple([tag | attrs])}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_instruction(str),
|
||||||
|
do:
|
||||||
|
str
|
||||||
|
|> instruction_parsec()
|
||||||
|
|> unwrap_parsec_result()
|
||||||
|
|
||||||
|
def circuit(), do: input_stream() |> Stream.map(&parse_instruction/1) |> Enum.into(%{})
|
||||||
|
|
||||||
def p1 do
|
def p1 do
|
||||||
|
:ets.new(:memo, [:set, :named_table])
|
||||||
|
|
||||||
|
circuit()
|
||||||
|
|> trace("a")
|
||||||
end
|
end
|
||||||
|
|
||||||
def p2 do
|
def p2 do
|
||||||
|
:ets.new(:memo, [:set, :named_table])
|
||||||
|
|
||||||
|
circuit()
|
||||||
|
|> Map.put("b", 956)
|
||||||
|
|> trace("a")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def trace(circuit, wire) when is_binary(wire) do
|
||||||
|
case :ets.lookup(:memo, wire) do
|
||||||
|
[{^wire, value}] ->
|
||||||
|
value
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
value = trace(circuit, Map.get(circuit, wire))
|
||||||
|
:ets.insert(:memo, {wire, value})
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(_circuit, signal) when is_integer(signal) do
|
||||||
|
signal
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(circuit, {:wire, wire}) do
|
||||||
|
trace(circuit, wire)
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(circuit, {:signal, signal}) do
|
||||||
|
trace(circuit, signal)
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(circuit, {:or, lhs, rhs}) do
|
||||||
|
trace(circuit, lhs) ||| trace(circuit, rhs)
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(circuit, {:and, lhs, rhs}) do
|
||||||
|
trace(circuit, lhs) &&& trace(circuit, rhs)
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(circuit, {:lshift, lhs, rhs}) do
|
||||||
|
trace(circuit, lhs) <<< trace(circuit, rhs)
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(circuit, {:rshift, lhs, rhs}) do
|
||||||
|
trace(circuit, lhs) >>> trace(circuit, rhs)
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(circuit, {:not, arg}) do
|
||||||
|
~~~trace(circuit, arg)
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace(_circuit, other), do: other
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue