// Silly but fun implementation of a binary->decimal conversion (function :Int binaryStringToDecimal [:String binary &opt :Bool invert] (apply + (for [idx digit] (enumerate (reverse (binary.split ""))) (* (let [digit (Std.parseInt digit)] (if invert (- 1 digit) digit)) (^ 2 idx))))) (assert (= 22 (binaryStringToDecimal "10110"))) (assert (= 9 (binaryStringToDecimal "10110" true))) (function :String mostCommonBit [:String binary &opt :String tieBreaker] (let [&mut ones 0.0 &mut total 0.0] (doFor digit (binary.split "") (+= total 1) (case digit ("1" (+= ones 1)) (otherwise))) (if (and tieBreaker (= ones (/ total 2))) tieBreaker (Std.string (Math.round (/ ones total)))))) (function :Int rate [:Array inputs :Bool epsilon] (binaryStringToDecimal (.join (for idx (range .length (first inputs)) (mostCommonBit (.join (for input inputs (input.charAt idx)) ""))) "") epsilon)) // Part 2 (function :Int otherRate [:Array inputs :Bool co2] (doFor idx (range .length (first inputs)) (let [mcb (mostCommonBit (.join (for input inputs (input.charAt idx)) "") "1") o2filter ->input (= (input.charAt idx) mcb) co2Filter ->input !(o2filter input)] (set inputs (filter inputs (if co2 co2Filter o2filter)))) (when (= 1 inputs.length) (return (binaryStringToDecimal (first inputs))))) null)