aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormryouse2023-06-04 18:01:46 +0000
committermryouse2023-06-04 18:01:46 +0000
commite79cd6c410f1e405b5c716d9ec4ce67ef7c4cf7a (patch)
tree02d2aed7e6d4f9672679f39d7ff73af2d6ba3710
parent519a55cc7ed30716608cb6758fbe6a820c85b645 (diff)
aoc 2021 day03 part2
-rw-r--r--aoc/2021/day03/part2.neb90
1 files changed, 90 insertions, 0 deletions
diff --git a/aoc/2021/day03/part2.neb b/aoc/2021/day03/part2.neb
new file mode 100644
index 0000000..1ff258c
--- /dev/null
+++ b/aoc/2021/day03/part2.neb
@@ -0,0 +1,90 @@
+;; https://adventofcode.com/2021/day/3
+
+(func bit-counts (inp)
+ (list
+ (length (filter (lambda (x) (eq? "0" x)) inp))
+ (length (filter (lambda (x) (eq? "1" x)) inp))))
+
+; treating bits as a string of 1s and 0s
+; note: for this problem, even if neb had byte things,
+; strings would probably still be the way to go
+(func bit-flip (bitstr)
+ (join
+ (map
+ (lambda (x) (if (eq? "0" x) "1" "0"))
+ (split bitstr))
+ ""))
+
+; 'exp' or something should be in the stdlib
+(func two-n (n)
+ (branch
+ ((eq? 0 n) 1)
+ ((eq? 1 n) 2)
+ (#true
+ (* 2 (two-n (- n 1))))))
+
+(func parse-binary (bitstr)
+ (parse-binary bitstr 0 0))
+
+(func parse-binary (bitstr pos acc)
+ (if (eq? 0 (length bitstr))
+ acc
+ (block
+ (def next-int (string->int (last bitstr)))
+ (if (eq? 0 next-int)
+ (parse-binary
+ (most bitstr)
+ (+ 1 pos)
+ acc)
+ (parse-binary
+ (most bitstr)
+ (+ 1 pos)
+ (+ acc
+ (two-n pos)))))))
+ ;(* 2 pos)))))))
+
+(func vertical-slice (inp idx)
+ (map
+ (lambda (x)
+ (first (slice x idx 1)))
+ inp))
+
+; since ox-gen and co2-scrub only differ in which
+; bit is considered the "winner" when comparing
+; bit counts, use a generic function
+(func generic-calc (inp idx bit-order)
+ (if (eq? 1 (length inp))
+ (parse-binary (first inp))
+ (block
+ (def val
+ (if (apply <= (bit-counts (vertical-slice inp idx)))
+ (first bit-order)
+ (last bit-order)))
+
+ (generic-calc
+ (filter
+ (lambda (x)
+ (eq? val (first (slice x idx 1))))
+ inp)
+ (+ 1 idx)
+ bit-order))))
+
+(func ox-gen-calc (inp idx)
+ (generic-calc inp idx (list "1" "0")))
+
+(func co2-scrub-calc (inp idx)
+ (generic-calc inp idx (list "0" "1")))
+
+(func do-the-thing (inp)
+ (def ox (ox-gen-calc inp 1))
+ (def co2 (co2-scrub-calc inp 1))
+ (print (concat "ox: " (->string ox)))
+ (print (concat "co2: " (->string co2)))
+ (print (concat "life support: " (->string (* ox co2)))))
+
+(def lines
+ (map split ; get all numbers as list of chars
+ (map strip
+ (read-lines "input.txt"))))
+
+(do-the-thing lines)