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/04.lisp | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/04.lisp (limited to 'src/04.lisp') 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)))))) -- cgit