You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.0 KiB
77 lines
2.0 KiB
#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))
|
|
|