From 475d382b0baaa085910d6066d3a51943e777b147 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 22 Dec 2021 15:02:02 +0100 Subject: Pass the 4th day in AOC --- src/03.lisp | 9 ++------ src/04.lisp | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/common.lisp | 15 ++++++++++++++ 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 src/04.lisp (limited to 'src') diff --git a/src/03.lisp b/src/03.lisp index a9cd314..2a4b2fa 100644 --- a/src/03.lisp +++ b/src/03.lisp @@ -10,11 +10,6 @@ (defun 03/parse-input (input-file) (03/parse-input-direct (get-file-lines input-file))) -;; Loops through two item windows on input and counts each time the first is less than the second -(defun 03/partial (func &rest args1) - (lambda (&rest args2) - (apply func (append args1 args2)))) - (defun 03/is-more (h l) (mapcar (lambda (x) (if (< x h) 0 1)) l)) @@ -29,11 +24,11 @@ (defun 03/find-most-common (parsed-input) (let ((half-length (/ (list-length parsed-input) 2))) - (03/is-more half-length (apply (03/partial #'mapcar #'+) parsed-input)))) + (03/is-more half-length (apply (partial #'mapcar #'+) parsed-input)))) (defun 03/find-least-common (parsed-input) (let ((half-length (/ (list-length parsed-input) 2))) - (03/is-less half-length (apply (03/partial #'mapcar #'+) parsed-input)))) + (03/is-less half-length (apply (partial #'mapcar #'+) parsed-input)))) (defun 03/part-a (parsed-input) (let* ((l (03/find-most-common parsed-input)) diff --git a/src/04.lisp b/src/04.lisp new file mode 100644 index 0000000..33436c2 --- /dev/null +++ b/src/04.lisp @@ -0,0 +1,64 @@ +(use-package 'cl-ppcre) +(use-package 'cl-utilities) +(use-package 'trivia) + +(defun 04/parse-input-direct (input) + (let ((in-list (mapcar #'parse-integer (split "," (car input)))) + (boards (mapcar (lambda (x) (mapcar (lambda (y) + (mapcar (lambda (z) + (list (parse-integer z) nil)) (split " +" (trim y)))) x)) + (split-sequence-if (lambda (x) (equalp x "")) (cddr input))))) + (list in-list boards))) + +(defun 04/parse-input (input-file) + (04/parse-input-direct (get-file-lines input-file))) + +(defun 04/update-board (num board) + (mapcar (lambda (row) + (mapcar (lambda (val) + (if (equalp num (car val)) (list (car val) t) val)) + row)) + board)) + +(defun rotate (list-of-lists) + (apply #'mapcar #'list list-of-lists)) + +(defun 04/check-rows (row) (every #'cadr row)) + +(defun 04/check-board (board) + (if (or (some #'04/check-rows board) + (some #'04/check-rows (rotate board))) + board nil)) + +;; (04/check-board '(((2 t) (3 nil)) ((2 nil) (3 t)))) +;; ==> nil + +(defun 04/to-val (v) (if (cadr v) 0 (car v))) + +(defun 04/sum-unmarked (board) + (apply #'+ (mapcar (compose + (partial #'apply #'+) + (partial #'mapcar #'04/to-val)) + board))) + +(defun 04/part-a (parsed-input) + (let ((inputs (car parsed-input)) + (boards (cadr parsed-input))) + (match (loop :for i :in inputs + :do (setf boards (mapcar (partial #'04/update-board i) boards)) + :when (some #'04/check-board boards) + :return (list i (some #'04/check-board boards))) + ((list i board) + (* i (04/sum-unmarked board)))))) + +(defun 04/part-b (parsed-input) + (let ((inputs (car parsed-input)) + (boards (cadr parsed-input))) + (match (loop :for i :in inputs + :do (setf boards (mapcar (partial #'04/update-board i) boards)) + :when (not (equalp (list-length boards) 1)) + :do (setf boards (filter (compose #'not #'04/check-board) boards)) + :when (and (equalp (list-length boards) 1) (04/check-board (car boards))) + :return (list i (car boards))) + ((list i board) + (* i (04/sum-unmarked board)))))) diff --git a/src/common.lisp b/src/common.lisp index c59ea79..2c56184 100644 --- a/src/common.lisp +++ b/src/common.lisp @@ -1,2 +1,17 @@ (defun get-file-lines (name) (uiop:read-file-lines name)) + +(defun partial (func &rest args1) + (lambda (&rest args2) + (apply func (append args1 args2)))) + +(defun compose (a b) + (lambda (&rest args) + (funcall a (apply b args)))) + +(defun filter (func l) + (loop :for i :in l :when (funcall func i) :collect i)) + +(defun trim (input) + (string-trim '(#\Space #\Newline #\Backspace #\Tab + #\Linefeed #\Page #\Return #\Rubout) input)) -- cgit