-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday06.roc
144 lines (120 loc) · 3.13 KB
/
day06.roc
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
app [part1, part2] {
pf: platform "https://github.com/ostcar/roc-aoc-platform/releases/download/v0.0.8/lhFfiil7mQXDOB6wN-jduJQImoT8qRmoiNHDB4DVF9s.tar.br",
array2d: "https://github.com/mulias/roc-array2d/releases/download/v0.3.1/2Jqajvxn36vRryyQBSluU6Fo6vVI5yNSYmcJcyaKp0Y.tar.br",
}
import array2d.Array2D
import array2d.Index2D
example =
"""
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...
"""
expect
got = part1 example
expected = Ok "41"
got == expected
part1 = \input ->
map = input |> parse
start = findStart? map
go? map start Up (List.withCapacity 40)
|> List.len
|> Num.add 1
|> Num.toStr
|> Ok
parse = \input ->
input
|> Str.trim
|> Str.splitOn "\n"
|> List.map \line ->
line
|> Str.toUtf8
|> Array2D.fromLists FitShortest
findStart = \map ->
map |> Array2D.findFirstIndex \e -> e == '^'
go = \map, current, direction, indexes ->
if List.contains indexes (direction, current) then
Err Loop
else
newIndexes = listAppendUnique indexes (direction, current)
when inFrontIndex map current direction is
Err OutOfBounds ->
indexes
|> List.map \(_, index) -> index
|> Set.fromList
|> Set.toList
|> Ok
Ok index ->
when Array2D.get? map index is
'#' ->
go map current (turn direction) newIndexes
'.' | '^' ->
go map index direction newIndexes
_ ->
Err InvalidInput
listAppendUnique = \list, element ->
if List.contains list element then
list
else
List.append list element
turn = \direction ->
when direction is
Up -> Right
Right -> Down
Down -> Left
Left -> Up
inFrontIndex = \map, current, direction ->
fn =
when direction is
Up -> decRow
Right -> incCol
Down -> incRow
Left -> decCol
fn current (Array2D.shape map)
decRow = \index, _shape ->
if Index2D.isColStart index then
Err OutOfBounds
else
Ok { index & row: index.row - 1 }
incRow = \index, shape ->
if Index2D.isColEnd index shape then
Err OutOfBounds
else
Ok { index & row: index.row + 1 }
decCol = \index, _shape ->
if Index2D.isRowStart index then
Err OutOfBounds
else
Ok { index & col: index.col - 1 }
incCol = \index, shape ->
if Index2D.isRowEnd index shape then
Err OutOfBounds
else
Ok { index & col: index.col + 1 }
expect
got = part2 example
expected = Ok "6"
got == expected
part2 = \input ->
# Err TODO
map = input |> parse
start = findStart? map
go map start Up []
|> try
|> List.walk 0 \acc, index ->
if index == start then
acc
else
changedMap = Array2D.set map index '#'
when go changedMap start Up [] is
Err Loop -> acc + 1
_ -> acc
|> Num.toStr
|> Ok