-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_03b.ex
94 lines (80 loc) · 2.26 KB
/
day_03b.ex
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
defmodule Day03b do
@input 312_051
defmodule Position do
defstruct [:x, :y]
end
defmodule Grid do
defstruct map: Map.new
def init(start_pos, value) do
%Grid{} |> put(start_pos, value)
end
def compute(grid, at: pos) do
value = sum_adj(grid, pos)
new_grid = put(grid, pos, value)
{new_grid, value}
end
def put(%Grid{map: map} = grid, %Position{x: x, y: y}, value) do
%{grid | map: Map.put(map, {x, y}, value)}
end
defp sum_adj(%Grid{map: map}, %Position{x: x, y: y}) do
[
Map.get(map, {x - 1, y - 1}, 0),
Map.get(map, {x , y - 1}, 0),
Map.get(map, {x + 1, y - 1}, 0),
Map.get(map, {x - 1, y }, 0),
Map.get(map, {x + 1, y }, 0),
Map.get(map, {x - 1, y + 1}, 0),
Map.get(map, {x , y + 1}, 0),
Map.get(map, {x + 1, y + 1}, 0),
] |> Enum.sum
end
end
defmodule Momentum do
defstruct [:dir, :step, :to_go]
def tick(%Momentum{to_go: to_go} = momentum) when to_go > 1 do
%{momentum | to_go: momentum.to_go - 1}
end
def tick(%Momentum{dir: :>, step: step} = m) do
%{m | dir: :A, to_go: step}
end
def tick(%Momentum{dir: :A, step: step} = m) do
%{m | dir: :<, to_go: step + 1, step: step + 1}
end
def tick(%Momentum{dir: :<, step: step} = m) do
%{m | dir: :V, to_go: step}
end
def tick(%Momentum{dir: :V, step: step} = m) do
%{m | dir: :>, to_go: step + 1, step: step + 1}
end
end
def run do
start_pos = %Position{x: 0, y: 0}
start_mom = %Momentum{dir: :>, step: 1, to_go: 1}
grid = Grid.init(start_pos, 1)
move(grid, start_pos, start_mom)
|> IO.inspect
end
def move(grid, pos, momentum) do
new_pos = step(pos, momentum)
{new_grid, value} = Grid.compute(grid, at: new_pos)
if value <= @input do
new_momentum = Momentum.tick(momentum)
move(new_grid, new_pos, new_momentum)
else
{pos, value}
end
end
def step(pos, %Momentum{dir: :>}) do
%{pos | x: pos.x + 1}
end
def step(pos, %Momentum{dir: :A}) do
%{pos | y: pos.y + 1}
end
def step(pos, %Momentum{dir: :<}) do
%{pos | x: pos.x - 1}
end
def step(pos, %Momentum{dir: :V}) do
%{pos | y: pos.y - 1}
end
end
Day03b.run