aoc2020/4.rkt

89 lines
2.8 KiB
Racket

#lang curly-fn racket
(require "scripts/aoc.rkt")
;; solution for day 4
;; helper functions here
(struct passport [byr iyr eyr hgt hcl ecl pid cid] #:transparent)
(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)))
(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)]
[_ #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?
(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))
(module+ test
(require rackunit)
;; tests here
(displayln "no tests :("))
(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))])))
;; part 1
(answer 4 1 (part1 input))
;; part 2
(answer 4 2 (part2 input))
(displayln "meow"))