;;;; 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)))))) (defun read-3 (file) (with-open-file (stream file) (let ((temp-map (loop for line = (read-line stream nil) while line collect line))) (make-array (list (length temp-map) (length (first temp-map))) :initial-contents temp-map :element-type 'character)))) (defun step-slope (position direction map) (let* ((temp-position (map 'list #'+ direction position)) (overflow (map 'list #'> temp-position (array-dimensions map)))) (cond ((first overflow) :bottom) ((second overflow) (progn (decf (second temp-position) (second (array-dimensions map))) temp-position)) (t temp-position)))) (defun solve-3-1 (direction map) (let ((tree-count 0)) (labels ((rec (position) (let ((zero-pos (map 'list #'1- position)) (new-pos (step-slope position direction map))) (if (char= (aref map (first zero-pos) (second zero-pos)) #\#) (incf tree-count)) (unless (eq new-pos :bottom) (rec new-pos))))) (rec '(1 1)) tree-count))) ;; (height width) (defun solve-3-2 (slopes map) (reduce #'* (loop for slope in slopes collecting (solve-3-1 slope map)))) (defun solve-3 (map) (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)))))