61 lines
1.9 KiB
Racket
61 lines
1.9 KiB
Racket
#lang curly-fn racket
|
|
|
|
(require "scripts/aoc.rkt")
|
|
|
|
;; solution for day 4
|
|
|
|
;; helper functions here
|
|
(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)
|
|
(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)) ((string-integer-in 150 193) h)]
|
|
[(pregexp #px"([0-9]+)in" (list _ h)) ((string-integer-in 59 76) h)]
|
|
[_ #f]))
|
|
|
|
(define pp-valid-part2?
|
|
(and/c pp-valid-part1?
|
|
(struct/c passport
|
|
(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)))
|
|
|
|
(define (part2 input)
|
|
(stream-count pp-valid-part2? (in-list input)))
|
|
|
|
(module+ main
|
|
(define input (map string->passport (string-split (file->string "inputs/4") "\n\n")))
|
|
|
|
;; part 1
|
|
(answer 4 1 (part1 input))
|
|
|
|
;; part 2
|
|
(answer 4 2 (part2 input))
|
|
|
|
(displayln "meow"))
|