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)