You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/2020/04.rkt

35 lines
1.4 KiB
Racket

4 years ago
#lang br
(require racket/file rackunit)
(define passports (for/list ([pstr (string-split (file->string "04.rktd") #rx"\n\n+")])
(for/hash ([kvstr (string-split pstr)])
(apply values (string-split kvstr ":")))))
(define required-fields '("byr" "iyr" "eyr" "hgt" "hcl" "ecl" "pid")) ; "cid" is not required
(define (passport-keys-valid? p)
(for*/and ([passport-keys (in-value (hash-keys p))]
[field required-fields])
(member field passport-keys)))
(check-equal? (count passport-keys-valid? passports) 202)
(define (stringval-in-range str low high)
(<= low (string->number str) high))
(define (passport-values-valid? p)
(and
(stringval-in-range (hash-ref p "byr") 1920 2002)
(stringval-in-range (hash-ref p "iyr") 2010 2020)
(stringval-in-range (hash-ref p "eyr") 2020 2030)
(let ([hgt (hash-ref p "hgt")])
(cond
[(string-suffix? hgt "cm") (stringval-in-range (string-trim hgt "cm") 150 193)]
[(string-suffix? hgt "in") (stringval-in-range (string-trim hgt "in") 59 76)]
[else #false]))
(let ([hcl (hash-ref p "hcl")])
(and (regexp-match #rx"#......" hcl) (string->number (string-trim hcl "#") 16)))
(member (hash-ref p "ecl") '("amb" "blu" "brn" "gry" "grn" "hzl" "oth"))
(let ([pid (hash-ref p "pid")]) (and (= 9 (string-length pid)) (string->number pid)))))
(check-equal? (count (λ (p) (and (passport-keys-valid? p) (passport-values-valid? p))) passports) 137)