-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay15.roc
146 lines (107 loc) · 3.51 KB
/
Day15.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
145
146
interface Day15 exposes [ output ] imports [ TestUtil ]
output : List I64 -> List (List I64)
output = \puzzleInput ->
testData1 = parseData testInput1
testData2 = parseData testInput2
testData3 = parseData testInput3
testData4 = parseData testInput4
testData5 = parseData testInput5
testData6 = parseData testInput6
testData7 = parseData testInput7
puzzleData = parseData puzzleInput
[ TestUtil.verify 15 1 1 (firstResult testData1 ) 436
, TestUtil.verify 15 1 2 (firstResult testData2 ) 1
, TestUtil.verify 15 1 3 (firstResult testData3 ) 10
, TestUtil.verify 15 1 4 (firstResult testData4 ) 27
, TestUtil.verify 15 1 5 (firstResult testData5 ) 78
, TestUtil.verify 15 1 6 (firstResult testData6 ) 438
, TestUtil.verify 15 1 7 (firstResult testData7 ) 1836
, TestUtil.show 15 1 (firstResult puzzleData)
, TestUtil.verify 15 2 1 (secondResult testData1 ) 175594
, TestUtil.verify 15 2 2 (secondResult testData2 ) 2578
, TestUtil.verify 15 2 3 (secondResult testData3 ) 3544142
, TestUtil.verify 15 2 4 (secondResult testData4 ) 261214
, TestUtil.verify 15 2 5 (secondResult testData5 ) 6895259
, TestUtil.verify 15 2 6 (secondResult testData6 ) 18
, TestUtil.verify 15 2 7 (secondResult testData7 ) 362
, TestUtil.show 15 2 (secondResult puzzleData)
]
# first part
firstResult : List I64 -> I64
firstResult = \data ->
last = getStart data 0 (List.repeat 2020 -1)
turn = List.len data
idx = List.len data - 1
num = read data idx
getResultHelper last 2020 turn num 0
getResultHelper : List I64, I64, I64, I64, I64 -> I64
getResultHelper = \last, turns, turn, num, lastTurn ->
if turn < turns then
newTurn = turn + 1
newNum =
if lastTurn > 0 then
turn - lastTurn
else
0
newLastTurn = read last newNum
newLast = List.set last newNum newTurn
getResultHelper newLast turns newTurn newNum newLastTurn
else
num
getStart : List I64, I64, List I64 -> List I64
getStart = \nums, idx, result ->
num = read nums idx
if num < 0 then
result
else
newIdx = idx + 1
turn = idx + 1
newResult = List.set result num turn
getStart nums newIdx newResult
read : List I64, I64 -> I64
read = \list, idx ->
when List.get list idx is
Ok n -> n
_ -> -1
# second part
secondResult : List I64 -> I64
secondResult = \data ->
last = getStart data 0 (List.repeat 30000000 -1)
turn = List.len data
idx = List.len data - 1
num = read data idx
getResultHelper last 30000000 turn num 0
# test data
parseData : List I64 -> List I64
parseData = \input ->
initial = { num : 0, nums: [] }
final = List.walk input parseWalker initial
List.append final.nums final.num
ParseAcc : { num : I64, nums : List I64 }
parseWalker : I64, ParseAcc -> ParseAcc
parseWalker = \val, acc ->
if val == 44 then
{ num: 0, nums: List.append acc.nums acc.num }
else
{ acc & num: 10 * acc.num + val - 48 }
testInput1 : List I64
testInput1 =
[ 48, 44, 51, 44, 54 ]
testInput2 : List I64
testInput2 =
[ 49, 44, 51, 44, 50 ]
testInput3 : List I64
testInput3 =
[ 50, 44, 49, 44, 51 ]
testInput4 : List I64
testInput4 =
[ 49, 44, 50, 44, 51 ]
testInput5 : List I64
testInput5 =
[ 50, 44, 51, 44, 49 ]
testInput6 : List I64
testInput6 =
[ 51, 44, 50, 44, 49 ]
testInput7 : List I64
testInput7 =
[ 51, 44, 49, 44, 50 ]