;;; https://jira.ringcentral.com/browse/ANY-13016 ;; (defparameter *day-12-file-name* "day12-test.txt") (defparameter *day-12-file-name* "day12-input.txt") (defparameter *day-12-lines* nil) (defparameter *day-12-start-coords nil) (defparameter *day-12-end-coords nil) (defparameter *array* nil) (defun restore-params () (setq *day-12-lines* (mapcar (lambda (line) (cl-ppcre:split "" line)) (uiop:read-file-lines *day-12-file-name*))) (setq *array* (make-array (list (length *day-12-lines*) (length (first *day-12-lines*))))) (destructuring-bind (rows cols) (array-dimensions *array*) (loop for row from 0 below rows do (loop for col from 0 below cols do (let* ((input-place-string (nth col (nth row *day-12-lines*))) (input-char (coerce input-place-string 'character))) (when (eq #\S input-char) (setq input-char #\a) (setq *day-12-start-coords (list row col)) ) (when (eq #\E input-char) (setq input-char #\z) (setq *day-12-end-coords (list row col)) ;; set end coords ) (setf (aref *array* row col) input-char)))))) (restore-params) *array* (array-dimensions *array*) *day-12-start-coords *day-12-end-coords ;; yay. (defun get-neighbors (row col) (list (list row (1- col)) (list (1- row) col) (list row (1+ col)) (list (1+ row) col))) (defun coord-in-dimentions (coords array) (destructuring-bind (row col) coords (destructuring-bind (rows cols) (array-dimensions array) (and (>= row 0) (>= col 0) (< row rows) (< col cols))))) (defun get-neighbors-in-array (coords array) (remove-if-not (lambda (coords) (when (coord-in-dimentions coords array) coords)) (apply #'get-neighbors coords ))) (defun move-valid-p (cur-char next-char) (>= 1 (- (char-code next-char) (char-code cur-char)))) ;; recursion (defun bfs-search-min-path (next-points-to-check) (if (not next-points-to-check) 999999 ; if exhausted reachable coords (let ((currently-checking (first next-points-to-check)) (rest-to-check (rest next-points-to-check))) (destructuring-bind (coords accum-path) currently-checking (if (equal coords *day-12-end-coords) accum-path (let* ((neighbour-coords (get-neighbors-in-array coords *array*)) (cur-char (aref *array* (first coords) (second coords))) (valid-next-steps (remove-if-not (lambda (coords) (let ((next-step-char (aref *array* (first coords) (second coords)))) (move-valid-p cur-char next-step-char))) neighbour-coords))) (format t "reaching coord ~a~%" coords) (setf (aref *array* (first coords) (second coords)) #\%) ;; format is '((1 1) 4) - coords and lenght-up-to (setq next-steps-with-length (mapcar (lambda (next-coords) (list next-coords (1+ accum-path))) valid-next-steps)) ;; (setf (aref *array* (first coords) (second coords)) cur-char) ;; (1+ (apply #'min lengts-from-next-steps)) (bfs-search-min-path (concatenate 'list rest-to-check next-steps-with-length)))))))) (bfs-search-min-path (list (list *day-12-start-coords 0))) ;; 339 ;; PART 2 (defparameter *day-12-2-starting-points '()) (defparameter *day-12-2-all-trail-lengts* nil) (progn ;; get starting points (destructuring-bind (rows cols) (array-dimensions *array*) (loop for row from 0 below rows do (loop for col from 0 below cols do (when (eq #\a (aref *array* row col)) (push `((,row ,col) 0) *day-12-2-starting-points))))) ;; calculate path lengths from all starting points (setq *day-12-2-all-trail-lengts* (loop for start-point in *day-12-2-starting-points collect (bfs-search-min-path (list start-point)) do (restore-params)))) ;; get shortest of them (first (sort *day-12-2-all-trail-lengts* #'<)) ;; yay. the shortest of all was 332