2 changed files with 1077 additions and 0 deletions
@ -0,0 +1,77 @@
|
||||
#lang racket |
||||
(require "lib/common.rkt" |
||||
threading) |
||||
|
||||
(define (binary->decimal binary) |
||||
(~>> binary |
||||
vector->list |
||||
list->string |
||||
(string-append "#b") |
||||
string->number)) |
||||
|
||||
(define (freqs-at lst idx) |
||||
(for/fold ([num-zeroes 0] |
||||
[num-ones 0] |
||||
#:result (cons num-zeroes num-ones)) |
||||
([num (in-list lst)]) |
||||
(match (vector-ref num idx) |
||||
[#\0 (values (add1 num-zeroes) num-ones)] |
||||
[#\1 (values num-zeroes (add1 num-ones))]))) |
||||
|
||||
(define (day3a lst) |
||||
(define (run ch1 ch2) |
||||
(for/vector ([i (in-range 0 (vector-length (first lst)))]) |
||||
(match-define (cons zeroes ones) (freqs-at lst i)) |
||||
(if (> zeroes ones) ch1 ch2))) |
||||
|
||||
(define gamma (run #\0 #\1)) |
||||
(define epsilon (run #\1 #\0)) |
||||
|
||||
(* (binary->decimal gamma) (binary->decimal epsilon))) |
||||
|
||||
(define (day3b lst) |
||||
(define (run ch1 ch2) |
||||
(let loop ([remaining lst] [i 0]) |
||||
(cond [(empty? (rest remaining)) (first remaining)] |
||||
[else |
||||
(match-define (cons zeroes ones) (freqs-at remaining i)) |
||||
(loop (filter (λ (num) |
||||
(equal? (vector-ref num i) |
||||
(if (<= zeroes ones) ch1 ch2))) |
||||
remaining) |
||||
(add1 i))]))) |
||||
|
||||
(define oxygen-generator (run #\1 #\0)) |
||||
(define co2-scrubber (run #\0 #\1)) |
||||
|
||||
(* (binary->decimal oxygen-generator) |
||||
(binary->decimal co2-scrubber))) |
||||
|
||||
(module+ main |
||||
(call-with-input-file "data/day3.txt" |
||||
(lambda (prt) |
||||
(define lines (map (compose list->vector string->list) (port->lines prt))) |
||||
(answer 3 1 (day3a lines)) |
||||
(answer 3 2 (day3b lines))))) |
||||
|
||||
(module+ test |
||||
(require rackunit) |
||||
|
||||
(define test-input |
||||
'("00100" |
||||
"11110" |
||||
"10110" |
||||
"10111" |
||||
"10101" |
||||
"01111" |
||||
"00111" |
||||
"11100" |
||||
"10000" |
||||
"11001" |
||||
"00010" |
||||
"01010")) |
||||
|
||||
(define lines (map (compose list->vector string->list) test-input)) |
||||
|
||||
(check-equal? (day3a lines) 198) |
||||
(check-equal? (day3b lines) 230)) |
Loading…
Reference in new issue