Initial commit
This commit is contained in:
commit
f242d2b0df
420 changed files with 62521 additions and 0 deletions
88
2020/day16/day16.rkt
Normal file
88
2020/day16/day16.rkt
Normal file
|
@ -0,0 +1,88 @@
|
|||
#lang racket
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (parse-ticket str)
|
||||
(map string->number (string-split str ",")))
|
||||
|
||||
(define (parse-rules lst)
|
||||
(for/hash ([str (in-list lst)])
|
||||
(define name (car (string-split str ": ")))
|
||||
(define ranges (map string->number (regexp-match* #px"\\d+" str)))
|
||||
(values name
|
||||
(λ (n) (or (<= (first ranges) n (second ranges))
|
||||
(<= (third ranges) n (fourth ranges)))))))
|
||||
|
||||
(define (read-input filename)
|
||||
(define in-str (file->string filename))
|
||||
(define rules (parse-rules (regexp-match* #px"[\\w ]+: \\d+-\\d+ or \\d+-\\d+" in-str)))
|
||||
(define my-ticket
|
||||
(parse-ticket (cadr (regexp-match #px"your ticket:\n([\\d,]+)" in-str))))
|
||||
(define nearby-tickets
|
||||
(map parse-ticket
|
||||
(string-split
|
||||
(cadr (regexp-match #px"nearby tickets:\n([\\d,\n]+)" in-str)))))
|
||||
(values rules my-ticket nearby-tickets))
|
||||
|
||||
(define (part1 filename)
|
||||
(define-values (rules my-ticket nearby-tickets) (read-input filename))
|
||||
(define invalid-values
|
||||
(for*/list ([ticket (in-list nearby-tickets)]
|
||||
[val (in-list ticket)]
|
||||
#:when (for/and ([(name rule-proc) (in-hash rules)])
|
||||
(not (rule-proc val))))
|
||||
val))
|
||||
(apply + invalid-values))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 "test1") 71))
|
||||
|
||||
(module+ main
|
||||
(displayln (part1 "input")))
|
||||
|
||||
(define ((valid? rules) ticket)
|
||||
(for/and ([val (in-list ticket)])
|
||||
(for/or ([(name rule-proc) (in-hash rules)])
|
||||
(rule-proc val))))
|
||||
|
||||
(define (field-positions h)
|
||||
(if (for/and ([(k v) (in-hash h)]) (= 1 (length v)))
|
||||
(for/hash ([(k v) (in-hash h)]) (values k (car v)))
|
||||
(begin
|
||||
(for ([(name lst) (in-hash h)]
|
||||
#:when (= 1 (length lst)))
|
||||
(for ([(other-name other-lst) (in-hash h)]
|
||||
#:unless (equal? other-name name))
|
||||
(hash-set! h other-name (remove (car lst) other-lst))))
|
||||
(field-positions h))))
|
||||
|
||||
(define (determine-ticket filename)
|
||||
(define-values (rules my-ticket nearby-tickets) (read-input filename))
|
||||
(define valid-tickets (filter (valid? rules) nearby-tickets))
|
||||
(define h (make-hash))
|
||||
(for ([(name rule-proc) (in-hash rules)])
|
||||
(hash-set! h name (range (length my-ticket))))
|
||||
(for ([(name rule-proc) (in-hash rules)]
|
||||
#:when #t
|
||||
[ticket (in-list valid-tickets)]
|
||||
#:when #t
|
||||
[val (in-list ticket)]
|
||||
[i (in-naturals)]
|
||||
#:when (not (rule-proc val)))
|
||||
(hash-update! h name (λ (lst) (remove i lst =))))
|
||||
(define positions (field-positions h))
|
||||
(for/hash ([(name pos) (in-hash positions)])
|
||||
(values name (list-ref my-ticket pos))))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (determine-ticket "test2") (hash "class" 12 "row" 11 "seat" 13)))
|
||||
|
||||
(define (part2 filename)
|
||||
(define ticket (determine-ticket filename))
|
||||
(apply * (for/list ([(name val) (in-hash ticket)]
|
||||
#:when (string-prefix? name "departure"))
|
||||
val)))
|
||||
|
||||
(module+ main
|
||||
(displayln (part2 "input")))
|
Loading…
Add table
Add a link
Reference in a new issue