118 lines
4.5 KiB
Common Lisp
118 lines
4.5 KiB
Common Lisp
;;; 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
|