Compare commits

...

2 Commits

Author SHA1 Message Date
efim 5990ef5d0b 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.
2022-12-10 19:45:39 +00:00
efim 3105b97f1d day 8 cleaning up code 2022-12-08 12:18:31 +00:00
5 changed files with 2361 additions and 1 deletions

View File

@ -227,7 +227,7 @@
(incf running-sum 1))))
running-sum))
;;; wow, 1835 was the right answer. urrgh
;;; wow, 1845 was the right answer. urrgh
;;; now to the second part
;; and that's totally different thing now.
;; i guess i could use my "col-line" to get coords to check from the tree
@ -367,6 +367,141 @@
(if (> cur-tree-score cur-max)
(setq cur-max cur-tree-score)))))
cur-max)
;; 230112 is the correct answer
;; wow. i got an aswer 8
;; now try to recalculate this horrible thing with actual input.
;;; let's CLEAN UP THE CODE, at least set it all together
;;; PART 1: Count visible trees
(defparameter *file-name* "day8-input.txt")
(progn
(defparameter *trees-2d-vector*
(let ((rows-accumulation ()))
(with-open-file (in *file-name*)
(loop
for line = (read-line in nil nil)
while line
do (push
(coerce (mapcar #'parse-integer (cl-ppcre:split "" line)) 'vector)
rows-accumulation)
)
(coerce (reverse rows-accumulation) 'vector))))
(defparameter *trees-rownum* (length *trees-2d-vector*))
(defparameter *trees-colnum* (length (aref *trees-2d-vector* 0))))
;; generate Visibility matrix for trees
(defparameter *tree-vis-matr*
(let* ((rows-count (length *trees-2d-vector*))
(cols-count (length (aref *trees-2d-vector* 0)))
(visibility-matrix (make-array (list rows-count cols-count) :initial-element nil)))
(iterate:iter (for rownum from 0 to (1- rows-count)) ; trying iter to avoid nested LOOP
(iterate:iter (for colnum from 0 to (1- cols-count))
(if (or (= rownum 0)
(= rownum (1- rows-count))
(= colnum 0)
(= colnum (1- cols-count)))
(setf (aref visibility-matrix rownum colnum) 'T))))
visibility-matrix))
;; get list of coordinates towards DIRECTION, starting from startRow & startCol
;; for generalizing LOOP'ing into different directions
(defun gen-line-coords (startRow startCol rowNum colNum direction)
(flet ((row-col-valid (row col)
(and (>= row 0) (>= col 0) (< row rowNum) (< col colNum)))
(nextPoint (row col)
(case direction
('LEFT (list row (1- col)))
('RIGHT (list row (1+ col)))
('UP (list (1- row) col))
('DOWN (list (1+ row) col)))))
(let ((coords-collected ()))
(do
((coords (list startRow startCol) (apply #'nextpoint coords)))
((not (apply #'row-col-valid coords)) (reverse coords-collected))
(push coords coords-collected)))))
(progn
;; this is with unfortunate amount of manual tinkering
(defparameter *trees-right-line-coords*
(loop
for startRow from 0 below *trees-rownum*
collect (gen-line-coords startRow 0 *trees-rownum* *trees-colnum* 'right)))
(defparameter *trees-left-line-coords*
(loop
for startRow from 0 below *trees-rownum*
collect (gen-line-coords startRow (1- *trees-colnum*) *trees-rownum* *trees-colnum* 'left)))
(defparameter *trees-right-down-coords*
(loop
for startCol from 0 below *trees-colnum*
collect (gen-line-coords 0 startCol *trees-rownum* *trees-colnum* 'down)))
(defparameter *trees-right-up-coords*
(loop
for startCol from 0 below *trees-colnum*
collect (gen-line-coords (1- *trees-rownum*) startCol *trees-rownum* *trees-colnum* 'up)))
(defparameter *trees-all-line-coords*
(concatenate 'list
*trees-right-line-coords*
*trees-left-line-coords*
*trees-right-down-coords*
*trees-right-up-coords*))
;;; iterate over all col-lines
(loop
for coord-line in *trees-all-line-coords*
do (let ((biggest-tree-so-far -1))
(loop
for coords in coord-line
do (let* ((rownum (first coords))
(colnum (second coords))
(row (aref *trees-2d-vector* rownum))
(tree-size (aref row colnum)))
(if (< biggest-tree-so-far tree-size)
(progn (setq biggest-tree-so-far tree-size)
(setf (aref *tree-vis-matr* rownum colnum) 't)))))))
*tree-vis-matr*
;; counting amount of 'T in the visibility matrix
(let ((running-sum 0))
(iterate:iter (for rownum from 0 to (1- *trees-rownum*))
(iterate:iter (for colnum from 0 to (1- *trees-colnum*))
(if (aref *tree-vis-matr* rownum colnum)
(incf running-sum 1))))
running-sum))
;;; PART 2. find tree with highest view-score
;; from list of tree-heights take trees that lover than current, until first tree of same height or higher
(defun my-get-prefix (trees-heights self-height)
(let ((self self-height)
(found-self nil))
(loop for elt in trees-heights
while (not found-self) collect elt
if (>= elt self) do (setq found-self 't))))
;; use same trees 2d array. O(n^2) - for each tree construct lines into 4 directions,
;; get prefix of these lines for trees that of not exceeding height, calculate score
;; instead of CUR-MAX could possibly use MAXIMIZING of LOOP, or something
(let ((cur-max -1))
(iterate:iter (for row from 1 to (1- *trees-rownum*))
(iterate:iter (for col from 1 to (1- *trees-colnum*))
(let* ((cur-tree-height (tree-size-by-coords (list row col)))
(cur-tree-lines (get-tree-direction-cols (list row col)))
(cur-tree-lines-tree-heights
(mapcar (lambda (coord-line)
(mapcar #'tree-size-by-coords coord-line)) cur-tree-lines))
(cur-tree-visibilities
(mapcar (lambda (height-list)
(length (my-get-prefix height-list cur-tree-height))) cur-tree-lines-tree-heights))
(cur-tree-score (apply #'* cur-tree-visibilities)))
(if (> cur-tree-score cur-max)
(setq cur-max cur-tree-score)))))
cur-max)

2000
day9-input.txt Normal file

File diff suppressed because it is too large Load Diff

209
day9-rope-bridge.lisp Normal file
View File

@ -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*)))

8
day9-test-bigger.txt Normal file
View File

@ -0,0 +1,8 @@
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20

8
day9-test.txt Normal file
View File

@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2