aoc2023/src/aoc10.lisp
2024-01-05 17:52:53 +01:00

192 lines
8 KiB
Common Lisp

(defun locate-starting-pos (string line-number)
(loop with starting-pos = nil
for c across string
for char-position from 0
do
(when (char= c #\S)
(setf starting-pos (cons char-position line-number)))
finally
(return starting-pos)))
(defun input-parsing (path)
(with-open-file (file path)
(let( (starting-pos nil) (line-length 0)
(node-array nil) (input-array (make-array 0 :adjustable t)) )
(loop with initial-line = (read-line file nil)
initially
;;(print initial-line)
(setf line-length (length initial-line))
(let( (size (+ 1 (length input-array))) )
(adjust-array input-array size) (decf size)
(setf (aref input-array size) (format nil "~a" initial-line)))
;;(setf input-string (format nil "~a~a" input-string line))
(setf starting-pos (locate-starting-pos initial-line 0))
for line = (read-line file nil)
for line-count from 1
while line
do
;;(print line)
;;(setf input-string (format nil "~a~a" input-string line))
(let( (size (+ 1 (length input-array))) )
(adjust-array input-array size) (decf size)
(setf (aref input-array size) (format nil "~a" line)))
(when (not starting-pos)
(setf starting-pos (locate-starting-pos line line-count)))
;;(setf node-array (make-array '(line-length line-count) :initial-element nil))
finally
;;(print line-length)
;;(print line-count)
(setf node-array (make-array (list line-length line-count) :initial-element nil))
(setf (aref node-array (cdr starting-pos) (car starting-pos)) t)
(return (values input-array node-array starting-pos))
))))
(defun determine-paths (input-array starting-pos)
(let ( (current-char nil) (paths-list (list 0 0 0 0)))
;;N
(when (not (equal (cdr starting-pos) 0))
(setf current-char (char (aref input-array (- (cdr starting-pos) 1)) (car starting-pos)))
(when (equal (nth 2 (gethash current-char *starting-orientation-hash*)) 1)
(setf (nth 0 paths-list) 1)))
;;W
(when (not (equal (car starting-pos) 0))
(setf current-char (char (aref input-array (cdr starting-pos)) (- (car starting-pos) 1)))
(when (equal (nth 3 (gethash current-char *starting-orientation-hash*)) 1)
(setf (nth 1 paths-list) 1)))
;;S
(when (not (equal (cdr starting-pos) (- (array-dimension input-array 0) 1)))
(setf current-char (char (aref input-array (+ (cdr starting-pos) 1)) (car starting-pos)))
(when (equal (nth 0 (gethash current-char *starting-orientation-hash*)) 1)
(setf (nth 2 paths-list) 1)))
;;E
(when (not (equal (car starting-pos) (- (length (aref input-array 0)) 1)))
(setf current-char (char (aref input-array (cdr starting-pos)) (+ (car starting-pos) 1)))
(when (equal (nth 1 (gethash current-char *starting-orientation-hash*)) 1)
(setf (nth 3 paths-list) 1)))
paths-list
))
(defun paths-list-to-starting-coords (paths-list starting-pos)
(loop for item in paths-list
for item-count from 0
with first-position = nil
with second-position = nil
while item
do
(when (not (zerop item))
(cond ((equal item-count 0) (setf first-position
(cons (car starting-pos) (- (cdr starting-pos) 1))))
((equal item-count 1) (if (not first-position)
(setf first-position
(cons (- (car starting-pos) 1) (cdr starting-pos) ))
(setf second-position
(cons (- (car starting-pos) 1) (cdr starting-pos) ))))
((equal item-count 2) (if (not first-position)
(setf first-position
(cons (car starting-pos) (+ (cdr starting-pos) 1)) )
(setf second-position
(cons (car starting-pos) (+ (cdr starting-pos) 1)) )))
(t (setf second-position
(cons (+ (car starting-pos) 1) (cdr starting-pos) )))))
finally
;;(print first-position)
;;(print second-position)
(return (values first-position second-position))))
(defun calculate-next-move (current-char current-position previous-position)
(let( (east-choice (cons (+ (car current-position) 1) (cdr current-position)))
(south-choice (cons (car current-position) (+ (cdr current-position) 1)))
(west-choice (cons (- (car current-position) 1) (cdr current-position)))
(north-choice (cons (car current-position) (- (cdr current-position) 1))) )
(format T "~%~a ~A~A" "nexmove from:" current-position previous-position)
;;(print current-position)
;;(print (car current-position))
;;(print north-choice)
;;(print west-choice)
(cond ((char= #\| current-char) (if (equal north-choice previous-position)
south-choice
north-choice))
((char= #\- current-char) (if (equal east-choice previous-position)
west-choice
east-choice))
((char= #\L current-char) (if (equal north-choice previous-position)
east-choice
north-choice))
((char= #\J current-char) (if (equal north-choice previous-position)
west-choice
north-choice))
((char= #\7 current-char) (if (equal south-choice previous-position)
west-choice
south-choice))
((char= #\F current-char) (if (equal south-choice previous-position)
east-choice
south-choice)))))
(defun steps-to-farthest-point (input-array node-array paths-list starting-pos)
;; (print "---")
(let( (circle-closed nil) (current-coords (list)) (previous-coords (list starting-pos starting-pos)))
(multiple-value-bind (first-position second-position)
(paths-list-to-starting-coords paths-list starting-pos)
(push first-position current-coords)
(push second-position current-coords)
(setf (aref node-array (cdr first-position) (car first-position)) t)
(setf (aref node-array (cdr second-position) (car second-position)) t)
;;(print node-array)
(print "----we gamin")
;;(print current-coords)
;;(print (calculate-next-move
(loop for steps from 1
while (not circle-closed)
do
(loop with current-char = nil
with temp-coords = nil
for index from 0
while (< index 2)
do
(setf current-char
(char (aref input-array (cdr (nth index current-coords)))
(car (nth index current-coords))) )
;;(print current-char)
;;(print
(setf temp-coords (calculate-next-move current-char (nth index current-coords)
(nth index previous-coords)))
(setf (nth index previous-coords) (nth index current-coords))
(setf (nth index current-coords) temp-coords)
(if (not (aref node-array (cdr (nth index current-coords))
(car (nth index current-coords))))
(setf (aref node-array (cdr (nth index current-coords))
(car (nth index current-coords)))t)
(setf circle-closed t))
;;(print node-array)
;;(print current-coords)
)
finally
(print steps)
)
;;(format T "~%~A~A" first-position second-position)
)))
;; (let( (input-array nil) (node-array nil) )
(defparameter *starting-orientation-hash* (make-hash-table :test #'equalp :size 7))
;;N-w-S-E
(setf (gethash #\| *starting-orientation-hash*) '(1 0 1 0))
(setf (gethash #\- *starting-orientation-hash*) '(0 1 0 1))
(setf (gethash #\L *starting-orientation-hash*) '(1 0 0 1))
(setf (gethash #\J *starting-orientation-hash*) '(1 1 0 0))
(setf (gethash #\7 *starting-orientation-hash*) '(0 1 1 0))
(setf (gethash #\F *starting-orientation-hash*) '(0 0 1 1))
(setf (gethash #\. *starting-orientation-hash*) '(0 0 0 0))
;;(print (gethash #\| *starting-orientation-hash*))
;;(multiple-value-bind (input-array node-array starting-pos) (input-parsing "aoc10test.txt") (format T "~%~A~%~A~%~A~A" input-array node-array starting-pos (determine-paths input-array starting-pos)))
(multiple-value-bind (input-array node-array starting-pos) (input-parsing "aoc10input.txt")
(format T "~%~A~%~A~%~A~%~A~%~a~%" input-array node-array starting-pos (determine-paths input-array starting-pos) "-----") (steps-to-farthest-point input-array node-array (determine-paths input-array starting-pos) starting-pos))
;;)