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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/2020/16.rkt

60 lines
2.3 KiB
Racket

4 years ago
#lang br
(require racket/file rackunit)
(match-define (list fields my-ticket other-tickets)
(string-split (file->string "16.rktd") "\n\n"))
(struct predicate (name func) #:transparent)
(define predicates
(for/list ([field (string-split fields "\n")])
(match (regexp-match #px"^(.*?): (\\d+)-(\\d+) or (\\d+)-(\\d+)$" field)
[(list* _ name numstrs)
(match-define (list val1 val2 val3 val4) (map string->number numstrs))
(predicate name (λ (x) (or (<= val1 x val2) (<= val3 x val4))))])))
(define (t2intvec t) (list->vector (map string->number (string-split t ","))))
(check-equal? (for*/sum ([ticket (cdr (string-split other-tickets "\n"))]
[intvec (t2intvec ticket)]
#:unless (for/or ([pred predicates])
((predicate-func pred) intvec)))
intvec) 26988)
(define all-tickets (cdr (string-split other-tickets "\n")))
(define (ticket-valid? ticket)
(for/and ([intvec (t2intvec ticket)])
(for/or ([pred predicates])
((predicate-func pred) intvec))))
(define valid-tickets (filter ticket-valid? all-tickets))
(define-values (departure-predicates other-predicates)
(partition (λ (p) (string-prefix? (predicate-name p) "departure")) predicates))
(define winning-idxss
(let loop ([extra-count 0])
(define predicates-to-test
(append departure-predicates (take other-predicates extra-count)))
(define possible-winning-idxss
(let ([valid-ticket-vecs (map t2intvec valid-tickets)])
(for/list ([idxs (in-combinations (range (length predicates))
(length predicates-to-test))]
#:when (for/and ([intvec valid-ticket-vecs])
(for/and ([idx idxs]
[pred departure-predicates])
((predicate-func pred) (vector-ref intvec idx)))))
idxs)))
(match possible-winning-idxss
[(list winner) (drop-right winner extra-count)]
[_ (loop (add1 extra-count))])))
;; too many possibilities
winning-idxss
#;(define my-ticket-intvec (t2intvec (cadr (string-split my-ticket "\n"))))
#;(for/product ([idx winning-idxs]
[pred departure-predicates])
(vector-ref my-ticket-intvec idx))