2 коммитов

Автор SHA1 Сообщение Дата
  Jens Kadenbach d62259bf75 Day 5 Part 2 2 лет назад
  Jens Kadenbach 5af46b73dd Day 5 Part 1 2 лет назад
9 измененных файлов: 753 добавлений и 2 удалений
  1. 8
    0
      aoc2022.cabal
  2. 1
    0
      package.yaml
  3. 511
    0
      ressources/day05-input
  4. 14
    0
      src/Day5.hs
  5. 25
    0
      src/Day5/Part1.hs
  6. 24
    0
      src/Day5/Part2.hs
  7. 84
    0
      src/Day5/Shared.hs
  8. 2
    2
      src/Lib.hs
  9. 84
    0
      test/Day5Spec.hs

+ 8
- 0
aoc2022.cabal Просмотреть файл

@@ -39,6 +39,10 @@ library
39 39
       Day4.Part1
40 40
       Day4.Part2
41 41
       Day4.Shared
42
+      Day5
43
+      Day5.Part1
44
+      Day5.Part2
45
+      Day5.Shared
42 46
       Lib
43 47
   other-modules:
44 48
       Paths_aoc2022
@@ -55,6 +59,7 @@ library
55 59
     , lens
56 60
     , split
57 61
     , text
62
+    , these
58 63
   default-language: Haskell2010
59 64
 
60 65
 executable aoc2022-exe
@@ -75,6 +80,7 @@ executable aoc2022-exe
75 80
     , lens
76 81
     , split
77 82
     , text
83
+    , these
78 84
   default-language: Haskell2010
79 85
 
80 86
 test-suite aoc2022-test
@@ -85,6 +91,7 @@ test-suite aoc2022-test
85 91
       Day2Spec
86 92
       Day3Spec
87 93
       Day4Spec
94
+      Day5Spec
88 95
       Paths_aoc2022
89 96
   hs-source-dirs:
90 97
       test
@@ -100,4 +107,5 @@ test-suite aoc2022-test
100 107
     , lens
101 108
     , split
102 109
     , text
110
+    , these
103 111
   default-language: Haskell2010

+ 1
- 0
package.yaml Просмотреть файл

@@ -30,6 +30,7 @@ dependencies:
30 30
 - split
31 31
 - lens
32 32
 - Ranged-sets
33
+- these
33 34
 
34 35
 ghc-options:
35 36
 - -Wall

+ 511
- 0
ressources/day05-input Просмотреть файл

@@ -0,0 +1,511 @@
1
+        [J]         [B]     [T]
2
+        [M] [L]     [Q] [L] [R]
3
+        [G] [Q]     [W] [S] [B] [L]
4
+[D]     [D] [T]     [M] [G] [V] [P]
5
+[T]     [N] [N] [N] [D] [J] [G] [N]
6
+[W] [H] [H] [S] [C] [N] [R] [W] [D]
7
+[N] [P] [P] [W] [H] [H] [B] [N] [G]
8
+[L] [C] [W] [C] [P] [T] [M] [Z] [W]
9
+ 1   2   3   4   5   6   7   8   9
10
+
11
+move 6 from 6 to 5
12
+move 2 from 5 to 9
13
+move 8 from 9 to 1
14
+move 3 from 5 to 4
15
+move 9 from 1 to 8
16
+move 2 from 1 to 5
17
+move 1 from 1 to 8
18
+move 14 from 8 to 2
19
+move 1 from 1 to 2
20
+move 2 from 6 to 8
21
+move 2 from 5 to 7
22
+move 6 from 8 to 6
23
+move 4 from 4 to 2
24
+move 2 from 4 to 9
25
+move 5 from 7 to 4
26
+move 2 from 7 to 5
27
+move 6 from 2 to 4
28
+move 2 from 4 to 7
29
+move 4 from 5 to 8
30
+move 1 from 5 to 2
31
+move 3 from 3 to 5
32
+move 3 from 8 to 3
33
+move 4 from 3 to 7
34
+move 2 from 9 to 8
35
+move 1 from 3 to 7
36
+move 1 from 6 to 8
37
+move 5 from 7 to 1
38
+move 3 from 7 to 2
39
+move 1 from 6 to 3
40
+move 2 from 5 to 9
41
+move 5 from 4 to 2
42
+move 3 from 5 to 9
43
+move 5 from 9 to 6
44
+move 2 from 1 to 3
45
+move 4 from 4 to 1
46
+move 2 from 8 to 1
47
+move 18 from 2 to 5
48
+move 3 from 4 to 1
49
+move 1 from 1 to 2
50
+move 1 from 6 to 8
51
+move 1 from 7 to 1
52
+move 10 from 1 to 5
53
+move 1 from 1 to 5
54
+move 3 from 8 to 1
55
+move 2 from 1 to 5
56
+move 3 from 6 to 5
57
+move 8 from 2 to 9
58
+move 2 from 9 to 7
59
+move 3 from 3 to 8
60
+move 1 from 4 to 8
61
+move 3 from 5 to 3
62
+move 15 from 5 to 8
63
+move 4 from 6 to 1
64
+move 2 from 7 to 4
65
+move 9 from 5 to 7
66
+move 1 from 6 to 8
67
+move 5 from 3 to 5
68
+move 5 from 7 to 5
69
+move 3 from 1 to 5
70
+move 2 from 4 to 8
71
+move 3 from 1 to 6
72
+move 20 from 5 to 4
73
+move 1 from 7 to 6
74
+move 21 from 8 to 2
75
+move 1 from 3 to 7
76
+move 2 from 4 to 2
77
+move 1 from 7 to 1
78
+move 18 from 2 to 8
79
+move 3 from 9 to 2
80
+move 1 from 6 to 4
81
+move 1 from 1 to 9
82
+move 8 from 8 to 6
83
+move 4 from 8 to 2
84
+move 1 from 2 to 6
85
+move 7 from 8 to 5
86
+move 2 from 5 to 3
87
+move 1 from 9 to 5
88
+move 5 from 2 to 4
89
+move 1 from 3 to 7
90
+move 2 from 5 to 7
91
+move 4 from 4 to 9
92
+move 2 from 5 to 9
93
+move 6 from 2 to 8
94
+move 3 from 7 to 3
95
+move 2 from 5 to 4
96
+move 4 from 8 to 2
97
+move 2 from 7 to 4
98
+move 7 from 6 to 4
99
+move 1 from 8 to 4
100
+move 3 from 6 to 7
101
+move 2 from 7 to 2
102
+move 7 from 9 to 7
103
+move 1 from 9 to 2
104
+move 3 from 3 to 6
105
+move 3 from 7 to 4
106
+move 2 from 7 to 9
107
+move 6 from 4 to 1
108
+move 3 from 7 to 9
109
+move 1 from 8 to 5
110
+move 1 from 3 to 6
111
+move 3 from 9 to 4
112
+move 2 from 6 to 4
113
+move 3 from 9 to 1
114
+move 4 from 2 to 8
115
+move 1 from 8 to 5
116
+move 9 from 1 to 2
117
+move 1 from 6 to 5
118
+move 1 from 7 to 2
119
+move 1 from 8 to 1
120
+move 2 from 8 to 9
121
+move 1 from 9 to 8
122
+move 1 from 5 to 7
123
+move 1 from 7 to 6
124
+move 1 from 9 to 8
125
+move 1 from 6 to 3
126
+move 26 from 4 to 3
127
+move 1 from 5 to 8
128
+move 3 from 6 to 3
129
+move 7 from 4 to 3
130
+move 1 from 1 to 3
131
+move 1 from 4 to 8
132
+move 13 from 3 to 1
133
+move 1 from 3 to 4
134
+move 12 from 2 to 5
135
+move 20 from 3 to 2
136
+move 1 from 4 to 1
137
+move 4 from 5 to 7
138
+move 1 from 7 to 8
139
+move 9 from 5 to 2
140
+move 5 from 1 to 5
141
+move 21 from 2 to 8
142
+move 5 from 8 to 4
143
+move 4 from 5 to 2
144
+move 6 from 1 to 7
145
+move 1 from 5 to 4
146
+move 4 from 3 to 1
147
+move 6 from 1 to 3
148
+move 1 from 1 to 9
149
+move 6 from 8 to 7
150
+move 4 from 8 to 2
151
+move 4 from 2 to 7
152
+move 5 from 4 to 1
153
+move 8 from 8 to 4
154
+move 1 from 9 to 6
155
+move 18 from 7 to 6
156
+move 15 from 6 to 5
157
+move 2 from 6 to 8
158
+move 2 from 6 to 3
159
+move 8 from 3 to 7
160
+move 15 from 5 to 7
161
+move 3 from 4 to 9
162
+move 12 from 2 to 3
163
+move 3 from 9 to 4
164
+move 6 from 7 to 9
165
+move 9 from 4 to 5
166
+move 10 from 3 to 5
167
+move 9 from 5 to 2
168
+move 14 from 7 to 8
169
+move 14 from 8 to 5
170
+move 4 from 2 to 4
171
+move 1 from 4 to 6
172
+move 2 from 8 to 4
173
+move 3 from 8 to 9
174
+move 18 from 5 to 1
175
+move 1 from 5 to 9
176
+move 1 from 7 to 4
177
+move 5 from 5 to 9
178
+move 3 from 2 to 4
179
+move 13 from 9 to 2
180
+move 13 from 2 to 6
181
+move 1 from 7 to 3
182
+move 3 from 3 to 1
183
+move 9 from 6 to 5
184
+move 1 from 7 to 8
185
+move 20 from 1 to 8
186
+move 2 from 2 to 8
187
+move 5 from 6 to 9
188
+move 15 from 8 to 7
189
+move 3 from 5 to 3
190
+move 5 from 1 to 3
191
+move 2 from 3 to 4
192
+move 3 from 9 to 5
193
+move 4 from 5 to 2
194
+move 4 from 5 to 7
195
+move 3 from 4 to 9
196
+move 10 from 7 to 8
197
+move 2 from 9 to 4
198
+move 1 from 5 to 6
199
+move 8 from 7 to 9
200
+move 1 from 6 to 7
201
+move 6 from 3 to 4
202
+move 12 from 9 to 8
203
+move 1 from 1 to 5
204
+move 2 from 7 to 8
205
+move 1 from 7 to 5
206
+move 1 from 9 to 5
207
+move 2 from 2 to 9
208
+move 11 from 8 to 1
209
+move 7 from 1 to 5
210
+move 3 from 1 to 6
211
+move 5 from 8 to 9
212
+move 8 from 4 to 3
213
+move 4 from 4 to 6
214
+move 5 from 9 to 3
215
+move 4 from 4 to 5
216
+move 2 from 6 to 7
217
+move 1 from 9 to 5
218
+move 2 from 7 to 4
219
+move 12 from 5 to 2
220
+move 8 from 8 to 9
221
+move 8 from 8 to 6
222
+move 9 from 6 to 2
223
+move 4 from 9 to 2
224
+move 1 from 5 to 1
225
+move 5 from 2 to 1
226
+move 2 from 5 to 4
227
+move 5 from 2 to 5
228
+move 5 from 5 to 6
229
+move 3 from 4 to 7
230
+move 11 from 2 to 7
231
+move 2 from 2 to 1
232
+move 4 from 3 to 7
233
+move 2 from 2 to 4
234
+move 6 from 1 to 4
235
+move 1 from 2 to 8
236
+move 2 from 9 to 5
237
+move 4 from 4 to 3
238
+move 5 from 4 to 1
239
+move 2 from 2 to 1
240
+move 1 from 8 to 5
241
+move 14 from 7 to 6
242
+move 3 from 9 to 2
243
+move 15 from 6 to 8
244
+move 4 from 1 to 3
245
+move 2 from 2 to 3
246
+move 1 from 1 to 7
247
+move 2 from 3 to 5
248
+move 4 from 5 to 4
249
+move 1 from 3 to 5
250
+move 5 from 1 to 6
251
+move 12 from 6 to 7
252
+move 7 from 8 to 4
253
+move 12 from 7 to 9
254
+move 4 from 7 to 9
255
+move 1 from 2 to 8
256
+move 12 from 9 to 4
257
+move 23 from 4 to 3
258
+move 1 from 6 to 5
259
+move 3 from 9 to 3
260
+move 1 from 7 to 9
261
+move 1 from 9 to 1
262
+move 1 from 9 to 7
263
+move 42 from 3 to 1
264
+move 3 from 5 to 4
265
+move 5 from 1 to 3
266
+move 3 from 4 to 7
267
+move 1 from 1 to 9
268
+move 4 from 3 to 8
269
+move 1 from 3 to 7
270
+move 1 from 9 to 1
271
+move 2 from 7 to 8
272
+move 8 from 1 to 6
273
+move 2 from 7 to 5
274
+move 9 from 1 to 2
275
+move 5 from 2 to 3
276
+move 3 from 2 to 4
277
+move 20 from 1 to 2
278
+move 1 from 1 to 5
279
+move 1 from 6 to 7
280
+move 3 from 4 to 7
281
+move 2 from 3 to 6
282
+move 3 from 6 to 1
283
+move 1 from 6 to 4
284
+move 2 from 1 to 6
285
+move 3 from 5 to 9
286
+move 1 from 4 to 3
287
+move 2 from 7 to 4
288
+move 6 from 8 to 4
289
+move 1 from 1 to 9
290
+move 1 from 2 to 9
291
+move 2 from 8 to 7
292
+move 3 from 6 to 2
293
+move 5 from 7 to 5
294
+move 4 from 2 to 5
295
+move 4 from 4 to 6
296
+move 3 from 9 to 6
297
+move 4 from 3 to 1
298
+move 1 from 9 to 2
299
+move 7 from 8 to 9
300
+move 4 from 2 to 4
301
+move 2 from 1 to 7
302
+move 3 from 4 to 5
303
+move 4 from 2 to 4
304
+move 1 from 7 to 4
305
+move 4 from 2 to 9
306
+move 7 from 4 to 3
307
+move 1 from 7 to 3
308
+move 6 from 2 to 3
309
+move 2 from 1 to 5
310
+move 10 from 3 to 6
311
+move 2 from 6 to 1
312
+move 2 from 2 to 7
313
+move 2 from 3 to 1
314
+move 1 from 7 to 8
315
+move 11 from 5 to 3
316
+move 2 from 3 to 1
317
+move 4 from 6 to 1
318
+move 1 from 4 to 6
319
+move 8 from 3 to 4
320
+move 2 from 5 to 6
321
+move 3 from 3 to 5
322
+move 1 from 8 to 4
323
+move 1 from 4 to 9
324
+move 2 from 6 to 1
325
+move 1 from 5 to 1
326
+move 9 from 4 to 3
327
+move 5 from 6 to 9
328
+move 5 from 6 to 7
329
+move 13 from 9 to 3
330
+move 5 from 1 to 8
331
+move 4 from 8 to 4
332
+move 10 from 3 to 2
333
+move 3 from 6 to 1
334
+move 2 from 7 to 9
335
+move 1 from 8 to 3
336
+move 1 from 7 to 3
337
+move 1 from 9 to 5
338
+move 1 from 6 to 3
339
+move 7 from 2 to 4
340
+move 3 from 5 to 2
341
+move 8 from 3 to 5
342
+move 7 from 4 to 3
343
+move 5 from 9 to 7
344
+move 1 from 7 to 1
345
+move 9 from 1 to 8
346
+move 9 from 5 to 8
347
+move 2 from 7 to 8
348
+move 3 from 8 to 1
349
+move 10 from 3 to 6
350
+move 1 from 1 to 6
351
+move 5 from 1 to 7
352
+move 3 from 2 to 8
353
+move 7 from 8 to 6
354
+move 7 from 8 to 6
355
+move 1 from 3 to 5
356
+move 5 from 7 to 9
357
+move 4 from 8 to 4
358
+move 3 from 2 to 8
359
+move 1 from 7 to 8
360
+move 3 from 3 to 9
361
+move 3 from 7 to 4
362
+move 1 from 7 to 2
363
+move 9 from 9 to 1
364
+move 5 from 1 to 9
365
+move 4 from 8 to 6
366
+move 1 from 2 to 7
367
+move 1 from 5 to 3
368
+move 1 from 3 to 7
369
+move 1 from 1 to 9
370
+move 1 from 1 to 7
371
+move 5 from 9 to 6
372
+move 2 from 7 to 6
373
+move 10 from 4 to 8
374
+move 1 from 4 to 2
375
+move 1 from 4 to 1
376
+move 1 from 9 to 2
377
+move 3 from 1 to 2
378
+move 1 from 7 to 3
379
+move 1 from 2 to 1
380
+move 16 from 6 to 3
381
+move 9 from 6 to 1
382
+move 6 from 6 to 1
383
+move 5 from 6 to 1
384
+move 3 from 8 to 1
385
+move 11 from 3 to 4
386
+move 1 from 6 to 2
387
+move 3 from 8 to 2
388
+move 4 from 1 to 6
389
+move 5 from 3 to 2
390
+move 1 from 2 to 5
391
+move 1 from 8 to 5
392
+move 5 from 8 to 3
393
+move 4 from 6 to 9
394
+move 2 from 9 to 6
395
+move 3 from 3 to 9
396
+move 1 from 5 to 7
397
+move 5 from 1 to 6
398
+move 3 from 6 to 4
399
+move 2 from 2 to 9
400
+move 8 from 4 to 2
401
+move 9 from 1 to 7
402
+move 3 from 3 to 5
403
+move 3 from 5 to 7
404
+move 12 from 7 to 1
405
+move 5 from 4 to 6
406
+move 1 from 4 to 5
407
+move 7 from 1 to 8
408
+move 5 from 9 to 3
409
+move 1 from 7 to 4
410
+move 10 from 1 to 8
411
+move 1 from 4 to 8
412
+move 4 from 6 to 8
413
+move 1 from 6 to 9
414
+move 2 from 5 to 1
415
+move 4 from 3 to 4
416
+move 1 from 1 to 8
417
+move 4 from 4 to 7
418
+move 2 from 1 to 8
419
+move 4 from 6 to 1
420
+move 3 from 9 to 5
421
+move 1 from 6 to 5
422
+move 1 from 3 to 7
423
+move 24 from 8 to 6
424
+move 3 from 6 to 5
425
+move 4 from 6 to 7
426
+move 1 from 1 to 7
427
+move 7 from 7 to 6
428
+move 7 from 5 to 3
429
+move 13 from 6 to 8
430
+move 3 from 1 to 2
431
+move 7 from 6 to 3
432
+move 12 from 2 to 4
433
+move 4 from 6 to 9
434
+move 6 from 3 to 1
435
+move 1 from 2 to 4
436
+move 2 from 8 to 7
437
+move 2 from 2 to 9
438
+move 6 from 3 to 4
439
+move 12 from 8 to 2
440
+move 18 from 2 to 5
441
+move 10 from 4 to 3
442
+move 4 from 7 to 3
443
+move 5 from 4 to 7
444
+move 3 from 5 to 2
445
+move 4 from 7 to 9
446
+move 1 from 5 to 4
447
+move 3 from 2 to 1
448
+move 4 from 3 to 6
449
+move 7 from 5 to 6
450
+move 2 from 5 to 7
451
+move 5 from 1 to 7
452
+move 9 from 7 to 6
453
+move 8 from 9 to 8
454
+move 1 from 1 to 3
455
+move 1 from 3 to 1
456
+move 10 from 3 to 9
457
+move 8 from 8 to 4
458
+move 1 from 3 to 8
459
+move 1 from 1 to 3
460
+move 6 from 9 to 1
461
+move 5 from 5 to 3
462
+move 5 from 3 to 6
463
+move 1 from 8 to 9
464
+move 19 from 6 to 2
465
+move 13 from 4 to 1
466
+move 4 from 1 to 5
467
+move 6 from 2 to 1
468
+move 2 from 9 to 4
469
+move 1 from 3 to 1
470
+move 9 from 2 to 3
471
+move 4 from 5 to 1
472
+move 5 from 9 to 6
473
+move 4 from 3 to 4
474
+move 3 from 2 to 7
475
+move 2 from 4 to 8
476
+move 6 from 1 to 9
477
+move 1 from 8 to 6
478
+move 4 from 1 to 5
479
+move 3 from 4 to 5
480
+move 1 from 7 to 2
481
+move 11 from 1 to 6
482
+move 1 from 2 to 7
483
+move 5 from 3 to 7
484
+move 1 from 3 to 4
485
+move 1 from 4 to 8
486
+move 3 from 5 to 6
487
+move 8 from 1 to 7
488
+move 1 from 8 to 9
489
+move 1 from 6 to 9
490
+move 1 from 8 to 5
491
+move 11 from 6 to 5
492
+move 12 from 5 to 2
493
+move 1 from 5 to 2
494
+move 8 from 7 to 3
495
+move 1 from 5 to 6
496
+move 2 from 5 to 6
497
+move 3 from 7 to 1
498
+move 6 from 2 to 6
499
+move 1 from 3 to 1
500
+move 1 from 4 to 1
501
+move 4 from 6 to 2
502
+move 5 from 1 to 5
503
+move 10 from 2 to 3
504
+move 2 from 9 to 4
505
+move 4 from 5 to 8
506
+move 2 from 2 to 7
507
+move 12 from 6 to 7
508
+move 1 from 8 to 2
509
+move 10 from 3 to 4
510
+move 2 from 3 to 5
511
+move 1 from 3 to 1

+ 14
- 0
src/Day5.hs Просмотреть файл

@@ -0,0 +1,14 @@
1
+module Day5 (day5) where
2
+
3
+import Day5.Part1
4
+import Day5.Part2
5
+
6
+
7
+day5 :: IO ()
8
+day5 = do
9
+   input <- readFile "ressources/day05-input"
10
+   putStrLn "Day5"
11
+   let message = day5_1 input
12
+   putStrLn ("Message from crates: " ++ message)
13
+   let secondMessage = day5_2 input
14
+   putStrLn ("Actuale message from crates: " ++ secondMessage)

+ 25
- 0
src/Day5/Part1.hs Просмотреть файл

@@ -0,0 +1,25 @@
1
+module Day5.Part1 (
2
+  executeOperation,
3
+  day5_1
4
+) where
5
+
6
+import qualified Data.Sequence as S
7
+import Data.Foldable (toList)
8
+import Day5.Shared
9
+
10
+executeOperation :: Row -> Operation -> Row
11
+executeOperation row op
12
+  | count op == 1 = updatedRow
13
+  | otherwise = executeOperation updatedRow (Operation { count = count op - 1, from = from op, to = to op })
14
+  where
15
+    originStack = row `S.index` asInt (from op)
16
+    targetStack = row `S.index` asInt (to op)
17
+    movedContent = head $ content originStack
18
+    updatedOrigin = Stack (drop 1 $ content originStack)
19
+    updatedTarget = Stack (movedContent : content targetStack)
20
+    updatedRow = S.update (asInt $ to op) updatedTarget $ S.update (asInt $ from op) updatedOrigin row
21
+
22
+day5_1 :: String -> String
23
+day5_1 input = toList . findTopOfStacks $ foldl executeOperation row operations
24
+  where
25
+    (row, operations) = parseInput input

+ 24
- 0
src/Day5/Part2.hs Просмотреть файл

@@ -0,0 +1,24 @@
1
+module Day5.Part2 (
2
+  execute9001Operation,
3
+  day5_2
4
+) where
5
+
6
+import qualified Data.Sequence as S
7
+import Data.Foldable (toList)
8
+import Day5.Shared
9
+
10
+execute9001Operation :: Row -> Operation -> Row
11
+execute9001Operation row op
12
+  = updatedRow 
13
+  where
14
+    originStack = row `S.index` asInt (from op)
15
+    targetStack = row `S.index` asInt (to op)
16
+    movedContent = take (count op) $ content originStack
17
+    updatedOrigin = Stack (drop (count op) $ content originStack)
18
+    updatedTarget = Stack (movedContent ++ content targetStack)
19
+    updatedRow = S.update (asInt $ to op) updatedTarget $ S.update (asInt $ from op) updatedOrigin row
20
+
21
+day5_2 :: String -> String
22
+day5_2 input = toList . findTopOfStacks $ foldl execute9001Operation row operations
23
+  where
24
+    (row, operations) = parseInput input

+ 84
- 0
src/Day5/Shared.hs Просмотреть файл

@@ -0,0 +1,84 @@
1
+module Day5.Shared (
2
+  StackIndex (..),
3
+  Operation (..),
4
+  Stack (..),
5
+  Row,
6
+  Content,
7
+  asInt,
8
+  content,
9
+  parseOperation,
10
+  parseStacks,
11
+  parseRow,
12
+  combineRows,
13
+  parseInput,
14
+  zipWithPadding,
15
+  findTopOfStacks
16
+) where
17
+
18
+import qualified Data.Sequence as S
19
+import Data.Sequence (Seq (..))
20
+
21
+newtype StackIndex = StackIndex Int deriving (Show, Eq, Ord)
22
+asInt :: StackIndex -> Int
23
+asInt (StackIndex i) = i - 1
24
+
25
+data Operation = Operation
26
+                    { count :: Int
27
+                    , from :: StackIndex
28
+                    , to :: StackIndex} deriving (Show, Eq)
29
+
30
+type Content = Char
31
+newtype Stack = Stack [Content] deriving (Show, Eq)
32
+
33
+content :: Stack  -> [Content]
34
+content (Stack c) = c
35
+
36
+instance Semigroup Stack where
37
+  (Stack x) <> (Stack y) = Stack (x ++ y)
38
+
39
+instance Monoid Stack where
40
+  mempty = Stack []
41
+
42
+type Row = S.Seq Stack
43
+
44
+parseOperation :: String -> Operation
45
+parseOperation line = Operation {
46
+ count = read $ parts !! 1,
47
+  from = StackIndex (read $ parts !! 3),
48
+  to = StackIndex (read $ parts !! 5)
49
+  }
50
+  where
51
+    parts = words line
52
+
53
+parseStacks :: [String] -> Row
54
+parseStacks input = foldl combineRows S.empty rows
55
+  where
56
+    rows = map parseRow input
57
+
58
+parseRow :: String -> Row
59
+parseRow ('[':c:']':' ':cs) = Stack [c] :<| parseRow cs
60
+parseRow (' ':' ':' ':' ':cs) = Stack [] :<| parseRow cs
61
+parseRow ['[', c, ']'] = S.singleton $ Stack [c]
62
+parseRow [' ', ' ', ' '] = S.singleton $ Stack []
63
+parseRow (' ':'1':_) = S.empty -- skip last line
64
+parseRow cs = error ("parseRow: unexpected Row \"" ++ cs ++ "\"")
65
+
66
+combineRows :: Row -> Row -> Row
67
+combineRows S.Empty row = row
68
+combineRows row S.Empty = row
69
+combineRows up down = S.fromList [x <> y | (x,y) <- zipWithPadding up down]
70
+
71
+zipWithPadding :: (Monoid a, Monoid b) => S.Seq a -> S.Seq b -> [(a,b)]
72
+zipWithPadding (x :<| xs)  (y :<| ys)  = (x,y) : zipWithPadding xs ys
73
+zipWithPadding S.Empty (y :<| ys)  = (mempty, y) : zipWithPadding S.empty ys
74
+zipWithPadding (x :<| xs)  S.Empty = (x, mempty) : zipWithPadding xs S.empty
75
+zipWithPadding S.Empty  S.Empty = []
76
+
77
+parseInput :: String -> (Row, [Operation])
78
+parseInput input = (parseStacks stackInput, map parseOperation (drop 1 operationInput))
79
+  where
80
+    (stackInput, operationInput) = break ("" ==) $ lines input
81
+
82
+
83
+findTopOfStacks :: Row -> Seq Content
84
+findTopOfStacks row = head . content <$> row

+ 2
- 2
src/Lib.hs Просмотреть файл

@@ -2,8 +2,8 @@ module Lib
2 2
     ( someFunc
3 3
     ) where
4 4
       
5
-import Day4      
5
+import Day5      
6 6
 
7 7
 someFunc :: IO ()
8
-someFunc = day4
8
+someFunc = day5
9 9
 

+ 84
- 0
test/Day5Spec.hs Просмотреть файл

@@ -0,0 +1,84 @@
1
+{-# LANGUAGE QuasiQuotes #-}
2
+module Day5Spec (spec) where
3
+
4
+import Test.Hspec
5
+import Text.Heredoc
6
+import qualified Data.Sequence as S
7
+
8
+import Day5.Part1
9
+import Day5.Part2
10
+import Day5.Shared
11
+
12
+inputPart1 :: String
13
+inputPart1 = [str|    [D]
14
+                 |[N] [C]
15
+                 |[Z] [M] [P]
16
+                 | 1   2   3
17
+                 |
18
+                 |move 1 from 2 to 1
19
+                 |move 3 from 1 to 3
20
+                 |move 2 from 2 to 1
21
+                 |move 1 from 1 to 2
22
+                 |]
23
+
24
+inputStacks :: String
25
+inputStacks = [str|    [D]
26
+                  |[N] [C]
27
+                  |[Z] [M] [P]
28
+                  | 1   2   3
29
+                  |]
30
+
31
+inputOperations :: String
32
+inputOperations = [str|move 1 from 2 to 1
33
+                      |move 3 from 1 to 3
34
+                      |move 2 from 2 to 1
35
+                      |move 1 from 1 to 2
36
+                      |]
37
+spec :: Spec
38
+spec =
39
+  describe "Day5" $ do
40
+    describe "Part1" $ do
41
+      it "parses Operations" $ do
42
+        let operation = head . lines $ inputOperations
43
+        parseOperation operation `shouldBe` Operation { count = 1, from = StackIndex 2, to = StackIndex 1 }
44
+      it "parses stacks" $ do
45
+        parseStacks (lines inputStacks) `shouldBe` S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
46
+      it "parses a single line of stacks" $ do
47
+        let row = head . lines $ inputStacks
48
+        parseRow row  `shouldBe` S.fromList [Stack "", Stack "D"]
49
+      it "combines stacks" $ do
50
+        (Stack "AB" <> Stack "CD") `shouldBe` Stack "ABCD"
51
+      it "combines rows" $ do
52
+        S.fromList [Stack "", Stack "A"] `combineRows` S.fromList [Stack "B", Stack "B"] `shouldBe` S.fromList [Stack "B", Stack "AB"]
53
+        S.empty `combineRows` S.fromList [Stack "B", Stack "B"] `shouldBe` S.fromList [Stack "B", Stack "B"]
54
+        S.fromList [Stack "A", Stack "B"] `combineRows` S.empty `shouldBe` S.fromList [Stack "A", Stack "B"]
55
+        S.singleton (Stack "") `combineRows` S.fromList[Stack "B", Stack "B"] `shouldBe` S.fromList [Stack "B", Stack "B"]
56
+        S.fromList [Stack "A", Stack "B"] `combineRows` S.singleton (Stack "") `shouldBe` S.fromList [Stack "A", Stack "B"]
57
+      it "splits input into stacks and operations" $ do
58
+        parseInput inputPart1 `shouldBe`
59
+         (S.fromList [Stack "NZ", Stack "DCM", Stack "P"],
60
+          [ Operation { count = 1, from = StackIndex 2, to = StackIndex 1},
61
+            Operation { count = 3, from = StackIndex 1, to = StackIndex 3},
62
+            Operation { count = 2, from = StackIndex 2, to = StackIndex 1},
63
+            Operation { count = 1, from = StackIndex 1, to = StackIndex 2}])
64
+      it "exeutes a count=1 operation on a row" $ do
65
+        let op = Operation { count = 1, from = StackIndex 2, to = StackIndex 3}
66
+        let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
67
+        executeOperation row op `shouldBe` S.fromList [Stack "NZ", Stack "CM", Stack "DP"]
68
+      it "exeutes a count > 1 operation on a row" $ do
69
+        let op = Operation { count = 2, from = StackIndex 2, to = StackIndex 3}
70
+        let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
71
+        executeOperation row op `shouldBe` S.fromList [Stack "NZ", Stack "M", Stack "CDP"]
72
+      it "finds the top items on stacks" $ do
73
+         let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
74
+         findTopOfStacks row `shouldBe` S.fromList "NDP"
75
+      it "solves the demo" $ do
76
+         day5_1 inputPart1 `shouldBe` "CMZ"
77
+    describe "Part1" $ do
78
+      it "executes 9001 operations on a row" $ do
79
+        let op = Operation { count = 2, from = StackIndex 2, to = StackIndex 3}
80
+        let row = S.fromList [Stack "NZ", Stack "DCM", Stack "P"]
81
+        execute9001Operation row op `shouldBe` S.fromList [Stack "NZ", Stack "M", Stack "DCP"]
82
+      it "solves the demo" $ do
83
+         day5_2 inputPart1 `shouldBe` "MCD"
84
+

Загрузка…
Отмена
Сохранить