;; 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)