194 lines
8 KiB
Common Lisp
194 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-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 "--")
|
|
(print node-array)
|
|
(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 "aoc10test.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))
|
|
|
|
;;)
|