;;;; AoC 2020 (defun read-1 (file) (with-open-file (stream file) (loop for line = (read-line stream nil) while line collect (parse-integer line)))) (defvar *input-1-0* nil) (setf *input-1-0* (read-1 "inputs/1-0")) (defvar *input-1-1* nil) (setf *input-1-1* (read-1 "inputs/1-1.txt")) (defun solve-1-1 (data target) (let ((deficits (map 'list (lambda (n) (- target n)) data))) (reduce #'* (intersection data deficits)))) (defun make-deficits (list difference) (map 'list (lambda (n) (- difference n)) list)) (defun solve-1-2 (data target) (let ((first-deficits (make-deficits data target))) (reduce #'* (remove-duplicates (mapcan (lambda (n) (intersection (make-deficits data n) data)) first-deficits))))) (defun solve-1 (data target) (time (progn (print (solve-1-1 data target)) (print (solve-1-2 data target))))) (defstruct password (pchar) (prange) (word)) (defun read-2 (file) (with-open-file (stream file) (loop for line = (read-line stream nil) while line collect (let* ((pwlist (split-sequence:split-sequence #\space line)) (range (multiple-value-bind (n index) (parse-integer (first pwlist) :junk-allowed t) (list n (parse-integer (first pwlist) :start (1+ index)))))) (make-password :pchar (char (second pwlist) 0) :prange range :word (third pwlist)))))) (defun %solve-2-1 (pw) (let ((n (count (password-pchar pw) (password-word pw)))) (and (not (> (first (password-prange pw)) n)) (not (< (second (password-prange pw)) n))))) (defun %solve-2-2 (pw) (let ((valid 0)) (loop for index in (password-prange pw) do (if (eq (password-pchar pw) (elt (password-word pw) (1- index))) (incf valid))) (= valid 1))) (defun %solve-2 (data test) (let ((pn 0)) (loop for p in data do (if (funcall test p) (incf pn))) pn)) (defun solve-2 (file) (let ((data (read-2 file))) (time (progn (print (%solve-2 data #'%solve-2-1)) (print (%solve-2 data #'%solve-2-2))))))