-
Notifications
You must be signed in to change notification settings - Fork 0
/
day8.exs
58 lines (46 loc) · 2.18 KB
/
day8.exs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
defmodule Register do
def find_max_register_end(filename) do
filename
|> parse_input
|> Enum.reduce({%{}, 0}, &parse_instruction/2)
|> elem(0)
|> Map.values()
|> Enum.max
end
def find_max_register_any(filename) do
filename
|> parse_input
|> Enum.reduce({%{}, 0}, &parse_instruction/2)
|> elem(1)
end
def parse_instruction(instruction, {registers, max_register_value}) do
{op_register, op, op_val, _, register, predicate, expected_val} = instruction
register_val = Map.get(registers, register, 0)
case predicate do
">" -> if register_val > expected_val do apply_op(registers, op_register, op, op_val, max_register_value) else {registers, max_register_value} end
">=" -> if register_val >= expected_val do apply_op(registers, op_register, op, op_val, max_register_value) else {registers, max_register_value} end
"<" -> if register_val < expected_val do apply_op(registers, op_register, op, op_val, max_register_value) else {registers, max_register_value} end
"<=" -> if register_val <= expected_val do apply_op(registers, op_register, op, op_val, max_register_value) else {registers, max_register_value} end
"==" -> if register_val == expected_val do apply_op(registers, op_register, op, op_val, max_register_value) else {registers, max_register_value} end
"!=" -> if register_val != expected_val do apply_op(registers, op_register, op, op_val, max_register_value) else {registers, max_register_value} end
_ -> {registers, max_register_value}
end
end
def apply_op(registers, register, op, val, max_val) do
{_, registers} = case op do
"inc" -> Map.get_and_update(registers, register, fn x -> {x, (x || 0) + val} end)
"dec" -> Map.get_and_update(registers, register, fn x -> {x, (x || 0) - val} end)
_ -> {nil, registers}
end
{registers, max(registers |> Map.values |> Enum.max, max_val)}
end
def parse_input(filename) do
filename
|> File.read!
|> String.trim
|> String.split("\n")
|> Enum.map(fn x -> String.split(x, " ") |> List.to_tuple end)
|> Enum.map(fn {register1, op, val1, control, register2, predicate, val2} ->
{register1, op, String.to_integer(val1), control, register2, predicate, String.to_integer(val2)} end)
end
end