alexandria-ocasio-cortez axiom-of-choice area-of-concern american-orthodox-church almost-optimal-coset solutions in the year of our lord 2021, I guess
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.

80 lines
2.6 KiB

#lang racket
(require "lib/common.rkt"
fancy-app)
(struct segment (signal-pattern output) #:transparent)
(define (parse lines)
(for/list ([line (in-list lines)])
(match-define `(,pat ,out) (string-split line "|"))
(segment (map (compose (apply set _) string->list)
(string-split pat))
(map (compose (apply set _) string->list)
(string-split out)))))
(define ((determine-digit patterns) seg)
(define (with-length len)
(for/list ([pattern (in-list patterns)]
#:when (= (set-count pattern) len))
pattern))
(define one (first (with-length 2)))
(define four (first (with-length 4)))
(define seven (first (with-length 3)))
(define eight (first (with-length 7)))
; fives are 2, 3, 5
; 2 intersect 3 intersect 5 = adg
(define adg (apply set-intersect (with-length 5)))
; adg union 1 = 3
(define three (set-union adg one))
; adg union 4 = 9
(define nine (set-union adg four))
; sixes are 0, 6, 9
; 6 intersect 9 intersect 0 = agf
(define agf (apply set-intersect (with-length 6)))
; f = agf minus adg
(define f (set-subtract agf adg))
; agf union adg = adgf, adgf union 4 = abcdgf, e = 8 minus abcdgf
(define e (set-subtract eight (set-union agf adg four)))
; two = three minus f union e
(define two (set-union (set-subtract three f) e))
; cf = 4 intersect 7, c = cf minus f
(define c (set-subtract (set-intersect four seven) f))
; six = 8 minus c
(define six (set-subtract eight c))
; five = 8 minus c minus e
(define five (set-subtract eight c e))
; zero = 8 minus adg union agf
(define zero (set-union (set-subtract eight adg) agf))
(cond [(set=? seg zero) #\0]
[(set=? seg one) #\1]
[(set=? seg two) #\2]
[(set=? seg three) #\3]
[(set=? seg four) #\4]
[(set=? seg five) #\5]
[(set=? seg six) #\6]
[(set=? seg seven) #\7]
[(set=? seg eight) #\8]
[(set=? seg nine) #\9]))
(define (day8a segs)
(for*/sum ([seg (in-list segs)]
[out (in-list (segment-output seg))]
#:when (or (= (set-count out) 2)
(= (set-count out) 3)
(= (set-count out) 4)
(= (set-count out) 7)))
1))
(define (day8b segs)
(for/sum ([seg (in-list segs)])
(match-define (segment pats outs) seg)
(string->number (apply string (map (determine-digit pats) outs)))))
(module+ main
(call-with-input-file "data/day8.txt"
(λ (prt)
(define segs (parse (port->lines prt)))
(answer 8 1 (day8a segs))
(answer 8 2 (day8b segs)))))