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.

84 lines
3.1 KiB
Racket

#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