day 4: cleaned up version
This commit is contained in:
parent
1b24d8142d
commit
bc82c7a528
96
4.rkt
96
4.rkt
|
@ -5,79 +5,51 @@
|
|||
;; solution for day 4
|
||||
|
||||
;; helper functions here
|
||||
(struct passport [byr iyr eyr hgt hcl ecl pid cid] #:transparent)
|
||||
(define-simple-macro (magic-struct name:id fld:id ...+)
|
||||
#:with fld-names (format-id #'name "~a-fields" #'name)
|
||||
(begin (struct name [fld ...] #:transparent)
|
||||
(define fld-names (map symbol->string '(fld ...)))))
|
||||
|
||||
(magic-struct passport byr iyr eyr hgt hcl ecl pid cid)
|
||||
|
||||
(define (string->passport str)
|
||||
(define pp (make-vector 8 #f))
|
||||
(for ([part (in-list (string-split str))])
|
||||
(match-define (list name val) (string-split part ":"))
|
||||
(vector-set! pp (index-of passport-fields name) val))
|
||||
(apply passport (vector->list pp)))
|
||||
|
||||
(define pp-valid-part1?
|
||||
(struct/c passport string? string? string? string? string? string? string? any/c))
|
||||
|
||||
(define (part1 input)
|
||||
(define pp-valid?
|
||||
(struct/c passport string? string? string? string? string? string? string? any/c))
|
||||
(for/sum ([pp (in-list input)] #:when (pp-valid? pp)) 1))
|
||||
|
||||
(define (part2 input)
|
||||
(define ((strlen/c num) str)
|
||||
(= (string-length str) num))
|
||||
|
||||
(define ((strnum-range/c low high) s)
|
||||
(define sn (string->number s))
|
||||
(and (number? sn)
|
||||
(<= low sn high)))
|
||||
(stream-count pp-valid-part1? (in-list input)))
|
||||
|
||||
(define (strlen/c num) (compose (=/c num) string-length))
|
||||
(define (string-integer-in low high) (compose (integer-in low high) string->number))
|
||||
(define (height/c hs)
|
||||
(match hs
|
||||
[(pregexp #px"([0-9]+)cm" (list _ h)) ((strnum-range/c 150 193) h)]
|
||||
[(pregexp #px"([0-9]+)in" (list _ h)) ((strnum-range/c 59 76) h)]
|
||||
[(pregexp #px"([0-9]+)cm" (list _ h)) ((string-integer-in 150 193) h)]
|
||||
[(pregexp #px"([0-9]+)in" (list _ h)) ((string-integer-in 59 76) h)]
|
||||
[_ #f]))
|
||||
|
||||
(define (hcolor/c cs)
|
||||
(match cs
|
||||
[(pregexp #px"#[0-9a-f]{6}") #t]
|
||||
[_ #f]))
|
||||
|
||||
(define (ecolor/c cs)
|
||||
(match cs
|
||||
[(or "amb" "blu" "brn" "gry" "grn" "hzl" "oth") #t]
|
||||
[_ #f]))
|
||||
|
||||
(define pp-valid?
|
||||
(define pp-valid-part2?
|
||||
(and/c pp-valid-part1?
|
||||
(struct/c passport
|
||||
(and/c string? (strlen/c 4) (strnum-range/c 1920 2002))
|
||||
(and/c string? (strlen/c 4) (strnum-range/c 2010 2020))
|
||||
(and/c string? (strlen/c 4) (strnum-range/c 2020 2030))
|
||||
(and/c string? height/c)
|
||||
(and/c string? hcolor/c)
|
||||
(and/c string? ecolor/c)
|
||||
(and/c string? (strlen/c 9) (strnum-range/c 0 999999999))
|
||||
any/c))
|
||||
(for/sum ([pp (in-list input)] #:when (pp-valid? pp)) 1))
|
||||
(and/c (strlen/c 4) (string-integer-in 1920 2002))
|
||||
(and/c (strlen/c 4) (string-integer-in 2010 2020))
|
||||
(and/c (strlen/c 4) (string-integer-in 2020 2030))
|
||||
height/c
|
||||
(curry regexp-match #px"#[0-9a-f]{6}")
|
||||
(or/c "amb" "blu" "brn" "gry" "grn" "hzl" "oth")
|
||||
(and/c (strlen/c 9) (string-integer-in 0 999999999))
|
||||
any/c)))
|
||||
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
;; tests here
|
||||
(displayln "no tests :("))
|
||||
(define (part2 input)
|
||||
(stream-count pp-valid-part2? (in-list input)))
|
||||
|
||||
(module+ main
|
||||
(define input-lines (file->lines "inputs/4"))
|
||||
|
||||
(define input
|
||||
(for/fold ([input (list (passport #f #f #f #f #f #f #f #f))]) ([line (in-list input-lines)])
|
||||
(define pp (first input))
|
||||
(cond
|
||||
[(zero? (string-length line)) (cons (passport #f #f #f #f #f #f #f #f) input)]
|
||||
[else
|
||||
(define parts (string-split line " "))
|
||||
(define new-pp
|
||||
(for/fold ([new-pp pp]) ([part (in-list parts)])
|
||||
(match-define (list name val) (string-split part ":"))
|
||||
(match name
|
||||
["byr" (struct-copy passport new-pp [byr val])]
|
||||
["iyr" (struct-copy passport new-pp [iyr val])]
|
||||
["eyr" (struct-copy passport new-pp [eyr val])]
|
||||
["hgt" (struct-copy passport new-pp [hgt val])]
|
||||
["hcl" (struct-copy passport new-pp [hcl val])]
|
||||
["ecl" (struct-copy passport new-pp [ecl val])]
|
||||
["pid" (struct-copy passport new-pp [pid val])]
|
||||
["cid" (struct-copy passport new-pp [cid val])]
|
||||
[_ (error "not shonks" line name val)])))
|
||||
(cons new-pp (rest input))])))
|
||||
(define input (map string->passport (string-split (file->string "inputs/4") "\n\n")))
|
||||
|
||||
;; part 1
|
||||
(answer 4 1 (part1 input))
|
||||
|
|
Loading…
Reference in New Issue