Login
7 branches 0 tags
Ben (X13/Arch) Simplified things a little 0643405 9 days ago 1260 Commits
nujel / tests / fast / day3.nuj
#!/usr/bin/env nujel

(def example-data "00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010")
(def input-data (file/read "tests/fast/day3.dat"))

(defn read-data (lines)
       (map (split lines "\n")
            (fn (line)
                (car (read (cat "#b" line))))))

(defn count-bits/single (number state bit-count)
       (def i 0)
       (while (< i bit-count)
              (def mask (bit-shift-left 1 i))
              (when (zero? (bit-and number mask))
                    (set! state i (+ 1 (ref state i))))
              (inc! i)))

(defn count-bits (numbers bit-count)
       (def count 0)
       (def state (:alloc Array bit-count))
       (array/fill! state 0)
       (while numbers
              (count-bits/single (car numbers) state bit-count)
              (cdr! numbers)
              (inc! count))
       {:bit-count bit-count :count count :zeroes state})

(defn calc-γε (state)
       (def i 0)
       (def γ 0)
       (def ε 0)
       (def threshold (bit-shift-right (ref state :count) 1))
       (def arr (ref state :zeroes))
       (while (< i (ref state :bit-count))
              (if (< (ref arr i) threshold)
                  (set! γ (bit-or γ (bit-shift-left 1 i)))
                  (set! ε (bit-or ε (bit-shift-left 1 i))))
              (inc! i))

       {:γ γ :ε ε :power-consumption (* ε γ)})

(def result (calc-γε (count-bits (read-data example-data) 5)))
(when (not= (ref result :power-consumption) 198)
      (throw (list :wrong-result "Wrong result" result)))

(def result (calc-γε (count-bits (read-data input-data) 12)))
(when (not= (ref result :power-consumption) 4103154)
      (throw (list :wrong-result "Wrong result" result)))

(return :success)