;; https://adventofcode.com/2021/day/3 (func one-most-common (inp) (> (length (filter (lambda (x) (eq? "1" x)) inp)) (/ (length inp) 2))) ; 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 do-the-thing (inp) ; i don't like the def/redef pattern ; this would benefit from something like "gather" ; this might also work as a map/reduce? (def out "") (for-count (length (first inp)) (def one? (one-most-common (map (lambda (x) (first (slice x _idx_ 1))) inp))) (redef out (concat out (if one? "1" "0")))) (print (->string (* (parse-binary out) (parse-binary (bit-flip out))))) ) (def lines (map split ; get all numbers as list of chars (map strip (read-lines "input.txt")))) (do-the-thing lines)