Advent of Code '23 - day 10
The first part was pretty straightforward, following a path till we reach our starting position. I skipped the second part for the time being.
Input
Examples
7-F7- .FJ|7 SJLL7 |F--J LJ.LJ
..... .S-7. .|.|. .L-J. .....
Part 1
(defun aoc23/parse-input (string) (let ((map (string-split string "\n" t)) (m (make-hash-table :test 'equal))) (puthash "map" map m) (puthash "h" (length map) m) (puthash "w" (length (car map)) m) m)) (defun aoc23/--node-at (p map) (elt (elt (gethash "map" map) (cdr p)) (car p))) (defun aoc23/translate (p translation) (cons (+ (car p) (car translation)) (+ (cdr p) (cdr translation)))) (defun aoc23/exits-at (p map) (let ((c (aoc23/node-at p map)) (x (car p)) (y (cdr p))) (cond ((= c ?.) nil) ((= c ?J) (list (aoc23/translate p '(0 . -1)) (aoc23/translate p '(-1 . 0)))) ((= c ?L) (list (aoc23/translate p '(0 . -1)) (aoc23/translate p '(1 . 0)))) ((= c ?7) (list (aoc23/translate p '(0 . 1)) (aoc23/translate p '(-1 . 0)))) ((= c ?F) (list (aoc23/translate p '(0 . 1)) (aoc23/translate p '(1 . 0)))) ((= c ?-) (list (aoc23/translate p '(-1 . 0)) (aoc23/translate p '(1 . 0)))) ((= c ?|) (list (aoc23/translate p '(0 . -1)) (aoc23/translate p '(0 . 1)))) ((= c ?S) (list (aoc23/translate p '(0 . -1)) (aoc23/translate p '(0 . 1)) (aoc23/translate p '(-1 . 0)) (aoc23/translate p '(1 . 0))))))) (defun aoc23/find-start (map) (let* ((w (1+ (gethash "w" map))) (m (apply 'concat (gethash "map" map))) (p (string-search "S" m)) (y (/ p w)) (x (% p w))) (cons x y))) (defun aoc23/stop-search-p (nodes) (let ((cars (mapcar 'car nodes))) (and (length> cars 1) (length= (seq-filter (lambda (n) (equal n (car cars))) cars) (length nodes))))) (defun aoc23/valid-node-p (node map) (let ((h (gethash "h" map)) (w (gethash "w" map)) (x (car node)) (y (cdr node))) (and (>= y 0) (< y h) (>= x 0) (< x w) (not (= (aoc23/--node-at node map) ?.))))) (defun aoc23/node-at (p map) (when (aoc23/valid-node-p p map) (aoc23/--node-at p map))) (let* ((map (aoc23/parse-input input)) (startp (aoc23/find-start map)) (current (list (cons startp nil))) (seen (list startp)) (steps 0)) (while current (let ((nnodes '())) (dolist (c current) (let* ((cn (car c)) (m (aoc23/exits-at cn map)) (m (seq-filter (lambda (c) (aoc23/valid-node-p c map)) m)) (newexits (seq-difference m seen)) (newexits (take 1 newexits)) (newnodes (mapcar (lambda (n) (cons n c)) newexits))) (setq nnodes (append nnodes newnodes)))) (setq current nnodes) (setq seen (append seen (mapcar 'car current)))) (setq steps (1+ steps))) (/ steps 2))