85 lines
2.7 KiB
Racket
85 lines
2.7 KiB
Racket
|
#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"))
|