You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
1.9 KiB
Racket
74 lines
1.9 KiB
Racket
3 years ago
|
#lang racket
|
||
|
|
||
|
; utility functions
|
||
|
|
||
|
(define (char->number char)
|
||
|
(if (equal? char #\0) 0 1))
|
||
|
|
||
|
(define (number->char num)
|
||
|
(if (= num 0) #\0 #\1))
|
||
|
|
||
|
(define (string->numbers str)
|
||
|
(map char->number (string->list str)))
|
||
|
|
||
|
(define (transpose xss)
|
||
|
(apply map list xss))
|
||
|
|
||
|
; IO
|
||
|
|
||
|
(define lines
|
||
|
(file->lines "day3.txt"))
|
||
|
|
||
|
(define chars
|
||
|
(map string->numbers lines))
|
||
|
|
||
|
; part 1
|
||
|
|
||
|
(define (count-ones-in-list xss)
|
||
|
(foldl + 0 (filter positive? xss)))
|
||
|
|
||
|
(define counts
|
||
|
(map count-ones-in-list (transpose chars)))
|
||
|
|
||
|
(define gamma-bin-list
|
||
|
(map (λ (count)
|
||
|
(if (> count (/ (length chars) 2)) 1 0))
|
||
|
counts))
|
||
|
|
||
|
(define (flip-bits num)
|
||
|
(map (λ (n) (modulo (+ 1 n) 2)) num))
|
||
|
|
||
|
(define epsilon-bin-list (flip-bits gamma-bin-list))
|
||
|
|
||
|
(define (binary-list->decimal num)
|
||
|
(string->number (list->string (map number->char num)) 2))
|
||
|
|
||
|
(define gamma-dec (binary-list->decimal gamma-bin-list))
|
||
|
(define epsilon-dec (binary-list->decimal epsilon-bin-list))
|
||
|
(define part1 (* gamma-dec epsilon-dec))
|
||
|
|
||
|
; part 2
|
||
|
; sounds like a fold to me
|
||
|
|
||
|
(define (most-common-digit column xs type)
|
||
|
(define col-values (map (λ (x) (list-ref x column)) xs))
|
||
|
(define ones (count-ones-in-list col-values))
|
||
|
(define op (if (equal? type 'o2) >= <)) ; 'o2 uses >=, 'co2 uses <
|
||
|
(if (op ones (/ (length xs) 2)) 1 0))
|
||
|
|
||
|
(define (get-rating xs type)
|
||
|
(flatten
|
||
|
(foldl (λ (column remaining)
|
||
|
(define most-common (most-common-digit column remaining type))
|
||
|
(if (= (length remaining) 1) ; if there's only one left
|
||
|
remaining ; return it
|
||
|
(filter (λ (ys)
|
||
|
(= (list-ref ys column) most-common))
|
||
|
remaining)))
|
||
|
xs
|
||
|
(range (length (first xs))))))
|
||
|
|
||
|
(define o2-rating (binary-list->decimal (get-rating chars 'o2)))
|
||
|
(define co2-rating (binary-list->decimal (get-rating chars 'co2)))
|
||
|
(define part2 (* o2-rating co2-rating))
|