blob: 49b4a7a17adae3ea30eedbb44846d81b74297d9c (
plain)
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
|
;; https://adventofcode.com/2021/day/4
; good candidate for loop-acc
(func get-all-boards (inp)
(def ret (list))
(for-count (/ (length inp) 5)
(redef ret (append ret
(get-board (slice inp (+ (* 5 (- _idx_ 1)) 1) 5)))))
ret)
(func get-board (inp)
(map get-row inp))
; each row is a string of items
; separated by (potentially) several spaces
; return a list of just the strings
(func get-row (row)
(filter
(lambda (x)
(not (eq? "" x)))
(split row " ")))
(func process-boards (inp)
(def raw-boards
(filter
(lambda (x) (not (eq? "" x)))
inp))
(get-all-boards raw-boards))
(def lines
(map strip
(read-lines "input.txt")))
(def moves (split (first lines) ",")) ; moves is the first line
(def boards (process-boards (rest lines)))
; this is a helper to work with zippers
; probably good to have in the stdlib
(func unzip (lst idx)
(list
(reverse
(slice lst 1 idx))
(slice lst (+ 1 idx))))
(func has-won-row (row)
(apply and row))
(func has-won (board moves)
(def checked (check-board board moves))
(def winner #false)
; check rows
; no break statement means we have to check everything,
; even after a winner is found
; can also use a while, but that would require more redefs
(for-each checked
(if (has-won-row _item_)
(redef winner #true)))
; no break here means we check columns even if we won on rows
; check columns
(for-count 5
(if (has-won-row
(map
(lambda (x) (first (slice x _idx_ 1)))
checked))
(redef winner #true)))
winner)
(func check-board (board moves)
(func check-row (row)
(map
(lambda (x)
(in? x moves))
row))
(map check-row board))
; how do we better iterate through this list?
; called/next would be perfect for a zipper
(def cur (list (list) moves)) ; init zip
(def winner #false)
(while (not winner)
(redef cur (unzip moves (+ 1 (length (first cur)))))
(print (->string cur))
(print (->string
(map
(lambda (x) (has-won x (first cur)))
boards)))
;(def checked (check-board (first boards) (first cur)))
;(print (->string checked))
(if (nil? (last cur))
(redef winner #true))
)
(print (->string moves))
;(print (->string (unzip moves 2)))
|