(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-count line-length) :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)) ;;)