|
|
|
#lang racket
|
|
|
|
|
|
|
|
(define (map-map f lst) ; map . map
|
|
|
|
(map (λ (x) (map (λ (y) (f y)) x)) lst))
|
|
|
|
|
|
|
|
(define data
|
|
|
|
(map-map string-split
|
|
|
|
(map (λ (l) (string-split l " | "))
|
|
|
|
(file->lines "day8.txt"))))
|
|
|
|
|
|
|
|
(define (is-easy? d)
|
|
|
|
(let ([len (string-length d)])
|
|
|
|
(or (= len 2) (= len 3) (= len 4) (= len 7))))
|
|
|
|
|
|
|
|
(define part1
|
|
|
|
(let* ([just-output (map second data)]
|
|
|
|
[just-easy-digits (map (λ (x) (filter is-easy? x)) just-output)])
|
|
|
|
(length (flatten just-easy-digits))))
|
|
|
|
|
|
|
|
part1
|
|
|
|
|
|
|
|
; part 2
|
|
|
|
|
|
|
|
; Can we just count the number of times a segment appears?
|
|
|
|
; No. Damn. But it gets us close. Naming the segments A - G
|
|
|
|
;
|
|
|
|
; A has 8 instances and IS NOT in 1
|
|
|
|
; B has 6 instances
|
|
|
|
; C has 8 instances and IS in 1
|
|
|
|
; D has 7 instances and IS in 4
|
|
|
|
; E has 4 instances
|
|
|
|
; F has 9 instances
|
|
|
|
; G has 7 instances and IS NOT in 4
|
|
|
|
|
|
|
|
(define (num-instances letter lst)
|
|
|
|
(length (filter (λ (s) (string-contains? s letter)) lst)))
|
|
|
|
|
|
|
|
(define letters '("a" "b" "c" "d" "e" "f" "g"))
|
|
|
|
|
|
|
|
(define (assign-segments lst) ; returns a vector with each position corresponing to a segment's letter. e.g. vect[0] = c, vect[1] = g, etc.
|
|
|
|
(let ([one (findf (λ (s) (= (string-length s) 2)) lst)]
|
|
|
|
[four (findf (λ (s) (= (string-length s) 4)) lst)])
|
|
|
|
(vector
|
|
|
|
(findf (λ (l) (and (= (num-instances l lst) 8) (not (string-contains? one l)))) letters) ; A has 8 instances and isn't in 1
|
|
|
|
(findf (λ (l) (= (num-instances l lst) 6)) letters) ; B
|
|
|
|
(findf (λ (l) (and (= (num-instances l lst) 8) (string-contains? one l))) letters) ; C
|
|
|
|
(findf (λ (l) (and (= (num-instances l lst) 7) (string-contains? four l))) letters) ; D
|
|
|
|
(findf (λ (l) (= (num-instances l lst) 4)) letters) ; E
|
|
|
|
(findf (λ (l) (= (num-instances l lst) 9)) letters) ; F
|
|
|
|
(findf (λ (l) (and (= (num-instances l lst) 7) (not (string-contains? four l)))) letters)))) ; G
|
|
|
|
|
|
|
|
(define (all-segments-in-str? key segments str)
|
|
|
|
(foldl (λ (seg all) (and all (string-contains? str (vector-ref key seg)))) true segments))
|
|
|
|
|
|
|
|
(define (segments->number lst key) ; takes some segments ("bc"), the key, and returns the corresponding number
|
|
|
|
(cond
|
|
|
|
[(and (= (string-length lst) 6) (all-segments-in-str? key '(0 1 2 4 5 6) lst)) 0]
|
|
|
|
[(= (string-length lst) 2) 1]
|
|
|
|
[(and (= (string-length lst) 5) (all-segments-in-str? key '(0 2 3 4 6) lst)) 2]
|
|
|
|
[(and (= (string-length lst) 5) (all-segments-in-str? key '(0 2 3 5 6) lst)) 3]
|
|
|
|
[(= (string-length lst) 4) 4]
|
|
|
|
[(and (= (string-length lst) 5) (all-segments-in-str? key '(0 1 3 5 6) lst)) 5]
|
|
|
|
[(and (= (string-length lst) 6) (all-segments-in-str? key '(0 1 3 4 5 6) lst)) 6]
|
|
|
|
[(= (string-length lst) 3) 7]
|
|
|
|
[(= (string-length lst) 7) 8]
|
|
|
|
[(and (= (string-length lst) 6) (all-segments-in-str? key '(0 1 2 3 5 6) lst)) 9]))
|
|
|
|
|
|
|
|
|
|
|
|
(define (num-list->number lst) ; '(1 2 3) -> 123
|
|
|
|
(string->number
|
|
|
|
(apply string-append
|
|
|
|
(map number->string lst))))
|
|
|
|
|
|
|
|
(define (line->number line)
|
|
|
|
(let* ([key (assign-segments (first line))]
|
|
|
|
[output (second line)]
|
|
|
|
[num-list (map (λ (s) (segments->number s key)) output)])
|
|
|
|
(num-list->number num-list)))
|
|
|
|
|
|
|
|
(define part2
|
|
|
|
(foldl (λ (l acc) (+ acc (line->number l))) 0 data))
|
|
|
|
|
|
|
|
part2
|