-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathday_02.ex
113 lines (91 loc) · 2.74 KB
/
day_02.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
defmodule AdventOfCode.Y2016.Day02 do
@moduledoc """
--- Day 2: Bathroom Security ---
Problem Link: https://adventofcode.com/2016/day/2
Difficulty: xs
Tags: grid rust
"""
alias AdventOfCode.Helpers.{InputReader, Transformers}
def input, do: InputReader.read_from_file(2016, 2)
@initial_position_1 5
@initial_position_2 [{"5", 2, 0}]
def run(input \\ input()) do
input = parse(input)
{run_1(input), run_2(input)}
end
def run_1(input) do
input
|> parse_rule([], @initial_position_1)
|> Enum.reverse()
|> Enum.join()
|> String.to_integer()
end
def run_2(input) do
data = to_matrix_map()
input
|> Enum.reduce(@initial_position_2, fn cmd, [{_, x, y} | _] = acc ->
[run_cmds(data, cmd, x, y) | acc]
end)
|> Enum.map_join(fn {v, _, _} -> v end)
|> String.split_at(-1)
|> elem(0)
|> String.reverse()
end
defp parse(input) do
input
|> Transformers.lines()
|> Enum.map(&String.graphemes/1)
end
defp valid?(number), do: number <= 0 or number > 9
defp next_1(cur, "L") when rem(cur, 3) != 1, do: cur - 1
defp next_1(cur, "R") when rem(cur, 3) != 0, do: cur + 1
defp next_1(cur, "U"), do: cur - 3
defp next_1(cur, "D"), do: cur + 3
defp next_1(_, _), do: -1
defp parse_rule([], res, _), do: res
defp parse_rule([h | t], [], position),
do: parse_rule(t, [find(h, position, &next_1/2)], position)
defp parse_rule([h | t], [x | _] = res, position),
do: parse_rule(t, [find(h, x, &next_1/2) | res], position)
defp find([], cur, _), do: cur
defp find([h | t], cur, next_fn) do
next_key = next_fn.(cur, h)
if valid?(next_key) do
find(t, cur, next_fn)
else
find(t, next_key, next_fn)
end
end
@matrix [
[nil, nil, "1", nil, nil],
[nil, "2", "3", "4", nil],
["5", "6", "7", "8", "9"],
[nil, "A", "B", "C", nil],
[nil, nil, "D", nil, nil]
]
def to_matrix_map(data \\ @matrix) do
data
|> Enum.with_index()
|> Map.new(fn {val, idx} ->
case val do
val when is_list(val) -> {idx, to_matrix_map(val)}
_ -> {idx, val}
end
end)
end
def run_cmds(data, [], x, y) do
{data[x][y], x, y}
end
def run_cmds(data, ["D" | rest], x, y) do
(data[x + 1][y] == nil && run_cmds(data, rest, x, y)) || run_cmds(data, rest, x + 1, y)
end
def run_cmds(data, ["U" | rest], x, y) do
(data[x - 1][y] == nil && run_cmds(data, rest, x, y)) || run_cmds(data, rest, x - 1, y)
end
def run_cmds(data, ["L" | rest], x, y) do
(data[x][y - 1] == nil && run_cmds(data, rest, x, y)) || run_cmds(data, rest, x, y - 1)
end
def run_cmds(data, ["R" | rest], x, y) do
(data[x][y + 1] == nil && run_cmds(data, rest, x, y)) || run_cmds(data, rest, x, y + 1)
end
end