From cf566277f84028c9cde2bf39da5b6ef2c51d519a Mon Sep 17 00:00:00 2001 From: 4903000 <4903000@chiru.no> Date: Fri, 4 Dec 2020 18:02:33 +0000 Subject: [PATCH] Day 4 --- aoc20.lisp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/aoc20.lisp b/aoc20.lisp index 819ca1b..30cb708 100644 --- a/aoc20.lisp +++ b/aoc20.lisp @@ -115,3 +115,64 @@ (time (let ((data (read-3 map))) (print (solve-3-1 '(1 3) data)) (print (solve-3-2 '((1 1) (1 3) (1 5) (1 7) (2 1)) data))))) + +(defvar *passport-fields* (list "byr" "iyr" "eyr" "hgt" "hcl" "ecl" "pid" "cid")) +(defvar *passport-rules-broken* (list nil nil nil nil nil nil nil (lambda (n) (declare (ignore n)) t))) +(defvar *passport-rules* nil) +(setf *passport-rules* + (list (lambda (n) (and n (let ((nn (ignore-errors (parse-integer n)))) + (and nn (>= nn 1920) (<= nn 2002))))) + (lambda (n) (and n (let ((nn (ignore-errors (parse-integer n)))) + (and nn (>= nn 2010) (<= nn 2020))))) + (lambda (n) (and n (let ((nn (ignore-errors (parse-integer n)))) + (and nn (>= nn 2020) (<= nn 2030))))) + (lambda (h) (and h (multiple-value-bind (n offset) (parse-integer h :junk-allowed t) + (let ((unit (subseq h offset))) + (cond ((string= unit "cm") + (and (>= n 150) (<= n 193))) + ((string= unit "in") + (and (>= n 59) (<= n 76)))))))) + (lambda (c) (and c + (= (length c) 7) + (char= (elt c 0) #\#) + (parse-integer (subseq c 1) :radix 16))) + (lambda (c) (and c (member c '("amb" "blu" "brn" "gry" "grn" "hzl" "oth") :test #'equal))) + (lambda (pid) (and pid + (= 9 + (length pid) + (length (remove-if (lambda (n) (not (digit-char-p n))) pid))))) + (lambda (cid) (declare (ignore cid)) t))) + +(defun read-passport (stream) + (let ((passport-list + (apply #'concatenate 'list + (loop for line = (read-line stream nil) + while (and line (not (string= line ""))) + collect (split-sequence:split-sequence #\space line)))) + (current-passport (make-hash-table :test 'equal))) + (loop for key in passport-list + do (setf (gethash (subseq key 0 3) current-passport) + (subseq key 4))) + current-passport)) + +(defun read-4 (file) + (with-open-file (stream file) + (loop while (peek-char nil stream nil) + collect (read-passport stream)))) + +(defun %solve-4 (data tests) + (let ((valid-count 0)) + (loop for passport in data + do (unless (member 'nil + (map 'list (lambda (field test) + (if test + (funcall test (gethash field passport)) + (gethash field passport))) + *passport-fields* tests)) + (incf valid-count))) + valid-count)) + +(defun solve-4 (file) + (let ((data (read-4 file))) + (time (progn (print (%solve-4 data *passport-rules-broken*)) + (print (%solve-4 data *passport-rules*))))))