adventofcode

https://adventofcode.com/
Log | Files | Refs

puzzle_4.scm (2849B)


      1 (load "read_lines.scm")
      2 (load "tokenize.scm")
      3 
      4 (define (right-fold passports)
      5   (if (not (null? passports))
      6     (if (not (= (string-length (car passports)) 0))
      7       (append (tokenize (car passports) #space) (right-fold (cdr passports)))
      8       (list (right-fold (cdr passports))))
      9     '()))
     10 
     11 (define (unfold passports)
     12   (if (not (null? passports))
     13     (let ((tail (reverse passports)))
     14       (if (not (pair? (car tail)))
     15         (list tail)
     16         (cons (cdr tail) (unfold (car tail)))
     17       ))
     18     '()))
     19 
     20 (define (get-fields passport)
     21   (map (lambda (field) (tokenize field #:)) passport))
     22 
     23 (define (range lo hi year)
     24   (let ((y (string->number year)))
     25     (and (>= y lo) (<= y hi))))
     26 
     27 (define (valid-height height)
     28   (let ((unit (substring height (- (string-length height) 2) (string-length height)))
     29         (h (string->number (substring height 0 (- (string-length height) 2)))))
     30     (if (string=? unit "cm")
     31         (and (>= h 150) (<= h 193))
     32         (and (string=? unit "in") (>= h 59) (<= h 76)))))
     33 
     34 (define (valid-hair-colour colour)
     35   (let ((c (string->list colour)))
     36     (and (char=? (car c) ##)
     37       (= (length (lset-intersection char=? (cdr c) (string->list "0123456789abcdef"))) (length (cdr c)))))) 
     38 
     39 (define (valid-eye-colour colour)
     40   (find (lambda (c) (string=? c colour)) eye-colours))
     41 
     42 (define (valid-passport-id id)
     43   (and (= (string-length id) 9)
     44   (= (length (lset-intersection char=? (string->list id) (string->list "0123456789"))) (string-length id))))
     45 
     46 (define (valid-fields passport)
     47   (and
     48     (range 1920 2002 (cadar (filter (lambda (field) (string=? (car field) "byr")) passport)))
     49     (range 2010 2020 (cadar (filter (lambda (field) (string=? (car field) "iyr")) passport)))
     50     (range 2020 2030 (cadar (filter (lambda (field) (string=? (car field) "eyr")) passport)))
     51     (valid-height (cadar (filter (lambda (field) (string=? (car field) "hgt")) passport)))
     52     (valid-hair-colour (cadar (filter (lambda (field) (string=? (car field) "hcl")) passport)))
     53     (valid-eye-colour (cadar (filter (lambda (field) (string=? (car field) "ecl")) passport)))
     54     (valid-passport-id (cadar (filter (lambda (field) (string=? (car field) "pid")) passport)))))
     55 
     56 (define batch (read-lines "files/4.txt" (lambda (x) x)))
     57 (define required '("byr" "iyr" "eyr" "hgt" "hcl" "ecl" "pid"))
     58 (define eye-colours '("amb" "blu" "brn" "gry" "grn" "hzl" "oth"))
     59 
     60 (define candidate-passports
     61   (filter (lambda (passport)
     62     (= (length (lset-intersection string=? (map (lambda (field) (car field)) (get-fields passport)) required)) 7))
     63     (unfold (right-fold batch))))
     64 
     65 (display (length candidate-passports)) (newline)
     66 
     67 (define valid-passports (filter (lambda (passport) (valid-fields passport))
     68                            (map (lambda (passport) (get-fields passport)) candidate-passports)))
     69 
     70 (display (length valid-passports)) (newline)