aboutsummaryrefslogtreecommitdiff
path: root/aoc/2021/day04
diff options
context:
space:
mode:
Diffstat (limited to 'aoc/2021/day04')
-rw-r--r--aoc/2021/day04/input.txt19
-rw-r--r--aoc/2021/day04/part01.neb101
2 files changed, 120 insertions, 0 deletions
diff --git a/aoc/2021/day04/input.txt b/aoc/2021/day04/input.txt
new file mode 100644
index 0000000..669a51d
--- /dev/null
+++ b/aoc/2021/day04/input.txt
@@ -0,0 +1,19 @@
+7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
+
+22 13 17 11 0
+ 8 2 23 4 24
+21 9 14 16 7
+ 6 10 3 18 5
+ 1 12 20 15 19
+
+ 3 15 0 2 22
+ 9 18 13 17 5
+19 8 7 25 23
+20 11 10 24 4
+14 21 16 12 6
+
+14 21 17 24 4
+10 16 15 9 19
+18 8 23 26 20
+22 11 13 6 5
+ 2 0 12 3 7
diff --git a/aoc/2021/day04/part01.neb b/aoc/2021/day04/part01.neb
new file mode 100644
index 0000000..49b4a7a
--- /dev/null
+++ b/aoc/2021/day04/part01.neb
@@ -0,0 +1,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)))