#lang curly-fn racket (require "scripts/aoc.rkt") ;; solution for day 16 (struct note [name rule0 rule1] #:transparent) (define (invalid? notes val) (not (for/or ([n (in-list notes)]) (match-define (note name (cons a b) (cons c d)) n) (or (and (>= val a) (<= val b)) (and (>= val c) (<= val d)))))) (define (part1 input) (match-define (list notes yours others) input) (for/sum ([tick (in-list others)]) (for/sum ([val (in-list tick)] #:when (invalid? notes val)) val))) (define (part2 input) (match-define (list notes yours others) input) (define (ticket-valid? tick) (not (for/or ([val (in-list tick)]) (invalid? notes val)))) (define valid-tickets (filter ticket-valid? others)) (define mapping (make-hash)) (for ([idx (in-range (length yours))]) (define decided-note (mutable-set)) (for ([cand-note (in-list notes)]) (define shonks (for/and ([tick (in-list valid-tickets)]) (not (invalid? (list cand-note) (list-ref tick idx))))) (when shonks (set-add! decided-note (note-name cand-note)))) (when (set-empty? decided-note) (error "couldn't decide...")) (hash-set! mapping idx decided-note)) ; (displayln mapping) (let loop () (for ([(k v) (in-hash mapping)]) (when (= 1 (set-count v)) (define fst (set-first v)) (for ([k2 (in-list (hash-keys mapping))] #:unless (= k2 k)) (set-remove! (hash-ref mapping k2) fst)))) (when (for/or ([(k v) (in-hash mapping)]) (> (set-count v) 1)) (displayln "looping") (loop))) (displayln mapping) (for/product ([val (in-list yours)] [idx (in-naturals)]) (define n (set-first (hash-ref mapping idx))) (displayln n) (if (string-contains? n "departure") (begin (displayln val) val) 1))) ;; parse input file (define (parse fname) (match-define (list notes yours others) (string-split (file->string fname) "\n\n")) (define sn string->number) (define pnotes (for/list ([line (in-list (string-split notes "\n"))]) (match line [(pregexp #px"^([^:]+): (\\d+)\\-(\\d+) or (\\d+)-(\\d+)$" (list _ name a b c d)) (note name (cons (sn a) (sn b)) (cons (sn c) (sn d)))]))) (define pyours (map sn (string-split (second (string-split yours "\n")) ","))) (define pothers (for/list ([line (in-list (rest (string-split others "\n")))]) (map sn (string-split line ",")))) (list pnotes pyours pothers)) (module+ test (require rackunit) ;; tests here (displayln "no tests :(")) (module+ main (define input (parse "inputs/16")) (answer 16 1 (time (part1 input))) (answer 16 2 (time (part2 input))) (displayln "meow"))