diff options
Diffstat (limited to 'aoc')
| -rw-r--r-- | aoc/2021/day03/part2.neb | 90 |
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) |
