day9 - line simulation
yes, maybe positive example of using macro - to allow my get-x being used as PLACE in setf but other modifications require variable. and that's not quite what i want.
This commit is contained in:
parent
3105b97f1d
commit
5990ef5d0b
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,209 @@
|
|||
;; https://adventofcode.com/2022/day/9
|
||||
|
||||
;; i have been thinking about this in a car on a way home.
|
||||
;; first check - if any movement of Tail is needed - if any coord is more than 2 away
|
||||
;;
|
||||
;; then - if movement is needed - it's always done in 1 step into direction of Head.
|
||||
;; - if difference is 0, no movement, otherwise (HeadX - TailX) / Abs(HeadX - TailX)
|
||||
;;
|
||||
;; and what's left is reading in changes to Head position, update of head position,
|
||||
;; and calling generation of new Tail position from newHead and prevTail
|
||||
;;
|
||||
;; no need to worry about the borders, as Head is always closer to border?
|
||||
|
||||
;; so, the field should be considered unbounded. and no coordinates for the starting point are given.
|
||||
;; we are also to consider that in the beginning Head is on top of Tail.
|
||||
;; ok. would my math work with negative coordinates? it really should
|
||||
;; so, let's consider starting coordinates as (0,0) and also keep a set of all preivously visited coordinates by the Tail
|
||||
;; and return its size
|
||||
(defmacro get-x (pointCoords)
|
||||
`(car ,pointCoords))
|
||||
(defmacro get-y (pointCoords)
|
||||
`(cadr ,pointCoords))
|
||||
|
||||
(setf (get-x '(1 2)) 3)
|
||||
(defparameter *test-list* (list 1 2))
|
||||
(setf (get-x *test-list*) 2)
|
||||
(setf (get-y *test-list*) 7)
|
||||
|
||||
(setf (first *test-list*) 3)
|
||||
(get-y '(1 2))
|
||||
|
||||
(abs -1)
|
||||
|
||||
|
||||
(defun tail-move-needed (headCoords tailCoords)
|
||||
(flet ((diff-more-than-two (num1 num2)
|
||||
(>= (abs (- num1 num2)) 2)))
|
||||
(or (diff-more-than-two (get-x headcoords) (get-x tailcoords))
|
||||
(diff-more-than-two (get-y headcoords) (get-y tailcoords)))))
|
||||
|
||||
(>= 2 2)
|
||||
(tail-move-needed '(1 1) '(1 1))
|
||||
(tail-move-needed '(1 1) '(1 2))
|
||||
(tail-move-needed '(1 1) '(1 3))
|
||||
(tail-move-needed '(1 1) '(2 3))
|
||||
(tail-move-needed '(1 1) '(0 0))
|
||||
|
||||
(defun update-big-distance-coord (headcoord tailcoord)
|
||||
(let* ((diff (- headcoord tailcoord))
|
||||
(change (if (eq diff 0) 0 (/ diff (abs diff)))))
|
||||
(+ tailcoord change)))
|
||||
|
||||
(defun update-big-distance-coords (headcoords tailcoords)
|
||||
(let ((new-x (update-big-distance-coord (get-x headcoords) (get-x tailcoords)))
|
||||
(new-y (update-big-distance-coord (get-y headcoords) (get-y tailcoords))))
|
||||
(list new-x new-y)))
|
||||
|
||||
(update-big-distance-coords '(2 1) '(0 0))
|
||||
(update-big-distance-coords '(-2 0) '(0 0))
|
||||
(update-big-distance-coords '(0 -2) '(0 0))
|
||||
|
||||
(defun get-new-tail-coords (headcoords tailcoords)
|
||||
(if (tail-move-needed headcoords tailcoords)
|
||||
(update-big-distance-coords headcoords tailcoords)
|
||||
tailcoords))
|
||||
|
||||
(get-new-tail-coords '(1 1) '(0 0))
|
||||
(get-new-tail-coords '(-1 0) '(0 0))
|
||||
(get-new-tail-coords '(1 -1) '(0 0))
|
||||
|
||||
;; ok, now i need to translate commands of type
|
||||
;; R 4
|
||||
(defparameter *test-line* "R 4")
|
||||
(require 'cl-ppcre)
|
||||
(let ((split (cl-ppcre:split " " *test-line*)))
|
||||
(setf (first split) (intern (first split)))
|
||||
(setf (second split) (parse-integer (second split)))
|
||||
split)
|
||||
|
||||
(defun read-comman (line)
|
||||
(let ((split (cl-ppcre:split " " line)))
|
||||
(setf (first split)
|
||||
(intern (first split)))
|
||||
(setf (second split)
|
||||
(parse-integer (second split)))
|
||||
split))
|
||||
|
||||
(read-comman "U 5")
|
||||
|
||||
(defun modify-head-coords (headcoords direction)
|
||||
(case direction
|
||||
(R (incf (get-x headcoords) 1))
|
||||
(L (incf (get-x headcoords) -1))
|
||||
(U (incf (get-y headcoords) 1))
|
||||
(D (incf (get-y headcoords) -1))))
|
||||
|
||||
(defparameter *test-coords* (list 0 0))
|
||||
(modify-head-coords *test-coords* 'L)
|
||||
(modify-head-coords *test-coords* 'R)
|
||||
(modify-head-coords *test-coords* 'U)
|
||||
(modify-head-coords *test-coords* 'D)
|
||||
|
||||
;; seems to work.
|
||||
;; now loop and addint tail coords into set
|
||||
(ql:quickload 'fset)
|
||||
(defparameter *test-set* (fset:set '(0 0) '(1 1)))
|
||||
(fset:with *test-set* '(3 1))
|
||||
(fset:with *test-set* '(1 1))
|
||||
;; yes, with equal, that's cool
|
||||
|
||||
(loop
|
||||
for i from 1 to 4
|
||||
do (print i))
|
||||
;; got I forgot most of what there is about input attribute
|
||||
;; modification, when will that modification become visible on top?
|
||||
;; when I've defined the value as parameter, so it's dynamic binding,
|
||||
;; instead of lexical binding?
|
||||
;; ((tail-coords-set (fset:empty-set))
|
||||
;; (headcoords (list 0 0))
|
||||
;; (tailcoords (list 0 0)))
|
||||
(progn
|
||||
(defvar tail-coords-set )
|
||||
(setq tail-coords-set (fset:empty-set))
|
||||
(defvar headcoords )
|
||||
(setq headcoords (list 0 0))
|
||||
(defvar tailcoords )
|
||||
(setq tailcoords (list 0 0)))
|
||||
|
||||
(defun run-step (direction)
|
||||
(modify-head-coords headcoords direction)
|
||||
(setf tailcoords (get-new-tail-coords headcoords tailcoords))
|
||||
(setf tail-coords-set (fset:with tail-coords-set tailcoords))
|
||||
;; (print (format t "~S ~S ~S~%" headcoords tailcoords direction))
|
||||
)
|
||||
|
||||
(defun run-command (repetitions direction)
|
||||
(loop for i from 1 to repetitions
|
||||
do (progn (run-step direction)
|
||||
;; (format t "~S ~S ~S ~S~%" headcoords tailcoords direction tail-coords-set)
|
||||
)))
|
||||
(progn
|
||||
(defvar tail-coords-set )
|
||||
(setq tail-coords-set (fset:empty-set))
|
||||
(defvar headcoords )
|
||||
(setq headcoords (list 0 0))
|
||||
(defvar tailcoords )
|
||||
(setq tailcoords (list 0 0))
|
||||
(with-open-file (in "day9-input.txt")
|
||||
(loop
|
||||
for line = (read-line in nil nil)
|
||||
while line
|
||||
do (let*
|
||||
((command (read-comman line))
|
||||
(direction (first command))
|
||||
(repetition (second command)))
|
||||
(run-command repetition direction)))
|
||||
(fset:size tail-coords-set)))
|
||||
|
||||
;;; PART 2
|
||||
;; i kind of predicted that they'd want to generalize to longer rope.
|
||||
;; ugh. but it still kind of works?
|
||||
;; just have list of rope points?
|
||||
;; and each step would be applying same step to some particular point
|
||||
;; - logging is not much less useful
|
||||
;; the points are H1234..9
|
||||
;; so, array of length 10
|
||||
(progn
|
||||
(defvar *string-joints*)
|
||||
;; (setq *string-joints* (make-array 10 :initial-element '(0 0)))
|
||||
;; wow, here's example of code being AST directly from text
|
||||
;; now, it's problem with "initial-element" cool
|
||||
(defvar *9-tail-coords-set*)
|
||||
(loop
|
||||
for i from 0 to 9
|
||||
do (setf (aref *string-joints* i) (list 0 0)))
|
||||
(setq *9-tail-coords-set* (fset:empty-set)))
|
||||
|
||||
(defun run-step-2 (direction)
|
||||
(modify-head-coords (aref *string-joints* 0) direction)
|
||||
(loop
|
||||
for cur-joint-step from 1 to 9
|
||||
do (setf (aref *string-joints* cur-joint-step)
|
||||
(get-new-tail-coords
|
||||
(aref *string-joints* (1- cur-joint-step))
|
||||
(aref *string-joints* cur-joint-step))))
|
||||
(setf *9-tail-coords-set*
|
||||
(fset:with *9-tail-coords-set* (aref *string-joints* 9))))
|
||||
|
||||
(defun run-command-2 (repetitions direction)
|
||||
(loop for i from 1 to repetitions
|
||||
do (progn (run-step-2 direction)
|
||||
;; (format t "~S ~S ~S ~S~%" headcoords tailcoords direction tail-coords-set)
|
||||
)))
|
||||
|
||||
(progn
|
||||
(loop
|
||||
for i from 0 to 9
|
||||
do (setf (aref *string-joints* i) (list 0 0)))
|
||||
(setq *9-tail-coords-set* (fset:empty-set))
|
||||
(with-open-file (in "day9-input.txt")
|
||||
(loop
|
||||
for line = (read-line in nil nil)
|
||||
while line
|
||||
do (let*
|
||||
((command (read-comman line))
|
||||
(direction (first command))
|
||||
(repetition (second command)))
|
||||
(run-command-2 repetition direction)))
|
||||
(fset:size *9-tail-coords-set*)))
|
|
@ -0,0 +1,8 @@
|
|||
R 5
|
||||
U 8
|
||||
L 8
|
||||
D 3
|
||||
R 17
|
||||
D 10
|
||||
L 25
|
||||
U 20
|
|
@ -0,0 +1,8 @@
|
|||
R 4
|
||||
U 4
|
||||
L 3
|
||||
D 1
|
||||
R 4
|
||||
D 1
|
||||
L 5
|
||||
R 2
|
Loading…
Reference in New Issue