day 3
This commit is contained in:
1000
day-3.input
Normal file
1000
day-3.input
Normal file
File diff suppressed because it is too large
Load Diff
75
day-3.scm
Normal file
75
day-3.scm
Normal file
@@ -0,0 +1,75 @@
|
||||
(import (srfi :43))
|
||||
|
||||
; returns a vector of 12 elements where each one counts the number
|
||||
; of times the n-th bit was zero in the input vector
|
||||
(define (count-zeroes-for-each-bit numbers)
|
||||
(let [(zeroes (make-vector 12 0))]
|
||||
(vector-for-each
|
||||
(lambda (index number)
|
||||
(let iterate [(bit 0)]
|
||||
(when (< bit 12)
|
||||
(when (= 0 (bitwise-and number
|
||||
(bitwise-arithmetic-shift-left 1 bit)))
|
||||
(vector-set! zeroes bit
|
||||
(+ 1 (vector-ref zeroes bit))))
|
||||
(iterate (+ 1 bit)))))
|
||||
numbers)
|
||||
zeroes))
|
||||
|
||||
(define (part-1 numbers)
|
||||
(let* [(zeroes (count-zeroes-for-each-bit numbers))]
|
||||
(let iter-loop [(i 0) (gamma 0)]
|
||||
(if (< i 12)
|
||||
; We don't need to compute the number of ones
|
||||
; as it is what's left when the zeroes are removed.
|
||||
; So that's just the number of elements minus the number of zeroes.
|
||||
(if (> (vector-ref zeroes i) (/ (vector-length numbers) 2))
|
||||
(iter-loop (+ i 1) (+ gamma (bitwise-arithmetic-shift-left 1 i)))
|
||||
(iter-loop (+ i 1) gamma))
|
||||
(let [(epsilon (bitwise-xor gamma #b111111111111))]
|
||||
(printf "part 1: ~% gamma: ~a~% epsilon: ~a~% power consumption: ~a~%"
|
||||
gamma epsilon (* gamma epsilon)))))))
|
||||
|
||||
; recursively filters the numbers checking for the n-th bit with the comparator
|
||||
; with <= as the comparator, it will check for bits that are set
|
||||
; with the opposite > comparator, it will check for bits that are not
|
||||
(define (determine-rating numbers comparator)
|
||||
(let loop [(bit 11)
|
||||
(numbers (vector-map (lambda (index number) number) numbers))]
|
||||
(if (= 1 (vector-length numbers))
|
||||
(vector-ref numbers 0)
|
||||
(let* [(zeroes (count-zeroes-for-each-bit numbers))
|
||||
(mask (bitwise-arithmetic-shift-left 1 bit))
|
||||
(target
|
||||
(if (apply comparator
|
||||
(list (vector-ref zeroes bit) (/ (vector-length numbers) 2)))
|
||||
0
|
||||
mask))]
|
||||
;(printf "dataset: ~a~% zeroes: ~a~% bit: ~a~% mask: (#b~b)~%" numbers zeroes bit mask)
|
||||
(loop
|
||||
(- bit 1)
|
||||
(vector-fold
|
||||
(lambda (index result number)
|
||||
(if (= target (bitwise-and number mask))
|
||||
(vector-append result (vector number))
|
||||
result))
|
||||
'#() numbers))))))
|
||||
|
||||
(define (part-2 numbers)
|
||||
(let [(oxygen-gen (determine-rating numbers <=))
|
||||
(co2-scrub (determine-rating numbers >))]
|
||||
(printf "part 2:~% O2-gen rating: ~a~% CO2-scrub rating: ~a~% life support: ~a~%"
|
||||
oxygen-gen co2-scrub (* oxygen-gen co2-scrub))))
|
||||
|
||||
(call-with-input-file
|
||||
"day-3.input"
|
||||
(lambda (file)
|
||||
(let [(numbers '#())]
|
||||
(let read-loop ()
|
||||
(let [(line (get-line file))]
|
||||
(when (not (eof-object? line))
|
||||
(set! numbers
|
||||
(vector-append numbers (vector (string->number line 2))))
|
||||
(read-loop))))
|
||||
(part-1 numbers)
|
||||
(part-2 numbers))))
|
||||
Reference in New Issue
Block a user