From 95a11e3602581e9a1d74b1196f21ca03283fb1c8 Mon Sep 17 00:00:00 2001 From: Oscar Najera Date: Thu, 14 Dec 2023 07:44:07 +0100 Subject: [AoC2023] day10 part1 lisp --- AoC2023/day10/solver.lisp | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 AoC2023/day10/solver.lisp (limited to 'AoC2023/day10/solver.lisp') diff --git a/AoC2023/day10/solver.lisp b/AoC2023/day10/solver.lisp new file mode 100644 index 0000000..fcc1eed --- /dev/null +++ b/AoC2023/day10/solver.lisp @@ -0,0 +1,87 @@ +;;05:32 + +(ql:quickload '(fiveam)) + +(defparameter directions + '((up 0 -1) + (dw 0 1) + (lf -1 0) + (rt 1 0))) + +(defparameter pipes + '((#\| up dw) + (#\- lf rt) + (#\L up rt) + (#\J up lf) + (#\7 dw lf) + (#\F dw rt) + (#\.) + (#\S up dw lf rt))) + +(defparameter eg-input + "7-F7- +.FJ|7 +SJLL7 +|F--J +LJ.LJ") + +(defun get-neighbors (point) + (mapcar + (lambda (dir) + (cdr (assoc dir directions))) + (cdr (assoc point pipes)))) + +(fiveam:test parts + (fiveam:is (equal '((-1 0) (1 0)) + (get-neighbors #\-)))) + + +(defun find-start (map) + (loop for row across map + for y from 0 do + (loop for col across row + for x from 0 + when (eq #\S col) + do (return-from find-start (list y x))))) + +(defun move-next (map point) + (flet ((bounds (y x) + (let ((ymax (length map)) + (xmax (length (aref map 0)))) + (when (and (< -1 y ymax) + (< -1 x xmax)) + (list y x))))) + (destructuring-bind (y x) point + (loop for (dx dy) in (get-neighbors (aref (aref map y) x)) + when (bounds (+ y dy) (+ x dx)) collect it)))) + +(defun start-neighbors (map start) + (remove-if-not + (lambda (n) + (member start (move-next map n) :test #'equal)) + (move-next map start))) + +(defun advance-next (map point last) + (let ((next (move-next map point))) + (if (equal last (car next)) + (cadr next) + (car next)))) + +(defun solver1 (rows) + (let* ((map (make-array (length rows) :initial-contents rows)) + (start (find-start map)) + (options (start-neighbors map start)) + (last start) + (cur (car options)) + ) + (loop + for next = (advance-next map cur last) + for steps from 1 + until (equal next start) + do (setf last cur + cur next) + finally (return (floor (+ steps 1) 2))))) + +(fiveam:test solution + (fiveam:is (= 8 (solver1 (uiop:split-string eg-input :separator '(#\Newline))))) + (fiveam:is (= 6812 (solver1 (uiop:read-file-lines "input"))))) -- cgit v1.2.3