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.
35 lines
1.4 KiB
Racket
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)
|