2020-12-16 05:31:34 +00:00
|
|
|
#lang curly-fn racket
|
|
|
|
|
|
|
|
(require "scripts/aoc.rkt")
|
|
|
|
|
|
|
|
;; solution for day 16
|
|
|
|
|
2020-12-16 05:53:10 +00:00
|
|
|
(struct note [name test] #:transparent)
|
2020-12-16 05:31:34 +00:00
|
|
|
|
2020-12-16 05:53:10 +00:00
|
|
|
(define (valid? notes val)
|
|
|
|
(ormap #{(note-test %) val} notes))
|
2020-12-16 05:31:34 +00:00
|
|
|
|
|
|
|
(define (part1 input)
|
|
|
|
(match-define (list notes yours others) input)
|
2020-12-16 05:53:10 +00:00
|
|
|
(for*/sum ([tick (in-list others)] [val (in-list tick)] #:unless (valid? notes val))
|
|
|
|
val))
|
2020-12-16 05:31:34 +00:00
|
|
|
|
|
|
|
(define (part2 input)
|
|
|
|
(match-define (list notes yours others) input)
|
2020-12-16 05:53:10 +00:00
|
|
|
(define valid-tickets (filter #{andmap #{valid? notes %} %} others))
|
2020-12-16 05:31:34 +00:00
|
|
|
|
2020-12-16 05:53:10 +00:00
|
|
|
(define mapping
|
|
|
|
(for/vector ([idx (in-range (length yours))])
|
|
|
|
(define matching-notes
|
|
|
|
(for/mutable-set ([cand-note (in-list notes)]
|
|
|
|
#:when (andmap #{valid? (list cand-note) (list-ref % idx)} valid-tickets))
|
|
|
|
(note-name cand-note)))
|
|
|
|
(when (set-empty? matching-notes) (error "couldn't decide..."))
|
|
|
|
matching-notes))
|
2020-12-16 05:31:34 +00:00
|
|
|
|
|
|
|
(let loop ()
|
2020-12-16 05:53:10 +00:00
|
|
|
(define has-conflicts #f)
|
|
|
|
(for ([v (in-vector mapping)] [k (in-naturals)])
|
|
|
|
(cond
|
|
|
|
[(= 1 (set-count v))
|
|
|
|
(define fst (set-first v))
|
|
|
|
(for ([v2 (in-vector mapping)] [k2 (in-naturals)] #:unless (= k2 k))
|
|
|
|
(set-remove! v2 fst))]
|
|
|
|
[else (set! has-conflicts #t)]))
|
|
|
|
(when has-conflicts
|
2020-12-16 05:31:34 +00:00
|
|
|
(loop)))
|
|
|
|
|
2020-12-16 05:53:10 +00:00
|
|
|
(for/product ([val (in-list yours)] [name-set (in-vector mapping)])
|
|
|
|
(if (string-contains? (set-first name-set) "departure")
|
|
|
|
val
|
2020-12-16 05:31:34 +00:00
|
|
|
1)))
|
|
|
|
|
|
|
|
;; parse input file
|
|
|
|
(define (parse fname)
|
|
|
|
(define sn string->number)
|
2020-12-16 05:53:10 +00:00
|
|
|
(match-define (list notes-in yours-in others-in) (string-split (file->string fname) "\n\n"))
|
|
|
|
(list (for/list ([line (in-list (string-split notes-in "\n"))])
|
|
|
|
(match line
|
|
|
|
[(pregexp #px"^([^:]+): (\\d+)\\-(\\d+) or (\\d+)-(\\d+)$"
|
|
|
|
(list _ name (app sn a) (app sn b) (app sn c) (app sn d)))
|
|
|
|
(note name #{or (<= a % b) (<= c % d)})]))
|
|
|
|
(map sn (string-split (second (string-split yours-in "\n")) ","))
|
|
|
|
(for/list ([line (in-list (rest (string-split others-in "\n")))])
|
|
|
|
(map sn (string-split line ",")))))
|
2020-12-16 05:31:34 +00:00
|
|
|
|
|
|
|
(module+ main
|
|
|
|
(define input (parse "inputs/16"))
|
|
|
|
(answer 16 1 (time (part1 input)))
|
|
|
|
(answer 16 2 (time (part2 input)))
|
|
|
|
(displayln "meow"))
|