#lang curly-fn racket (require "scripts/aoc.rkt") ;; solution for day 16 (struct note [name test] #:transparent) (define (valid? notes val) (ormap #{(note-test %) val} notes)) (define (part1 input) (match-define (list notes yours others) input) (for*/sum ([tick (in-list others)] [val (in-list tick)] #:unless (valid? notes val)) val)) (define (part2 input) (match-define (list notes yours others) input) (define valid-tickets (filter #{andmap #{valid? notes %} %} others)) (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)) (let loop () (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 (loop))) (for/product ([val (in-list yours)] [name-set (in-vector mapping)]) (if (string-contains? (set-first name-set) "departure") val 1))) ;; parse input file (define (parse fname) (define sn string->number) (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 ","))))) (module+ main (define input (parse "inputs/16")) (answer 16 1 (time (part1 input))) (answer 16 2 (time (part2 input))) (displayln "meow"))