;; https://adventofcode.com/2022/day/17 ;; so. cool. ;; one thought - i'd want to learn how to specify smaller argument types for optimizations ;; another - better think of optimizing checks ;; one more - reads from array should be faster, write new figure only after it comes to rest ;; thinking of checks. i could have separate methods that check 'possible left|right|down movement' ;; so. is there a cycle datastructure? ;; yes, but not in standart library, just cycle the list on itself (defun circular (items) (setf (cdr (last items)) items) items) (circular '(2 5 8 )) (type-of '(1 . 7)) (typep '(1 . 7) '(cons fixnum fixnum)) (declaim (ftype (function (string (cons fixnum fixnum)) string) test-types)) (defun test-types (s tup) (format nil "~a here, sup ~a~%" tup s)) (test-types "hello" '(1 . 4)) ;; cool, but i want for separate arguments, so that it could be also used in defgeneric ? (defun test-types-2 (ss tt str) (declare (type string ss) (type (cons fixnum string) tt) ;; (type 'string str) ) (format t "~a ~a ~a" ss tt str)) (test-types-2 "hello" '(1 . "yy") 13) ;; that works! ;; and will probably work with defgeneric? (defgeneric test-types-3 (obj str) (declare (ignore str))) ;; doesn't work. ;; http://www.lispworks.com/documentation/HyperSpec/Body/m_defgen.htm ;; only allows "optimize" declaration ;; The special, ftype, function, inline, notinline, and declaration declarations are not permitted. Individual implementations can extend the declare option to support additional declarations. ;; OK ;; so, do i want to have separate classes and generic methods for checking left | bottom | right? ;; possibly, yes. and for printing ;; how do I select "anchor point"? from which i'd do checking? ;; well, HM. it could be always lowest point, i guess ;; how'd i do the check for moving left? ;; pass in array, and coord of the anchor, compute locally coords to check and check array content at that point (defparameter *test-grid* nil) (defun init-test-grid (height) (declaim (type fixnum height)) (setq *test-grid* (let* ((grid (make-array `(,height 7) :initial-element #\.)) (rownum (1- (array-dimension grid 0))) (rowsize (array-dimension grid 1)) (row (make-array rowsize :displaced-to grid :displaced-index-offset (* rownum rowsize)))) (loop for i from 0 below (array-total-size row) do (setf (aref row i) #\_)) grid)) nil) (init-test-grid) (defun print-grid (grid ) (let ((rows (array-dimension grid 0)) (rowsize (array-dimension grid 1))) (terpri) (loop for rownum from 0 below rows do (let ((row-arr (make-array rowsize :displaced-to grid :displaced-index-offset (* rownum rowsize)))) (format t "|~a|~%" (coerce row-arr 'string) ))) (terpri))) (print-grid *test-grid* ) (print-grid *test-grid* ) ; well, it will hardly be helpful without specifying slice. if we're to drop Ks and Ms of stones *test-grid* ;; (ql:quickload 'array-operations) ;; what's displaced array? would it be easy to get rows from multidimentional that way? ;; https://lispcookbook.github.io/cl-cookbook/arrays.html ;; The reduce function operates on sequences, including vectors (1D arrays), but not on multidimensional arrays. ;; To get around this, multidimensional arrays can be displaced to create a 1D vector. ;; Displaced arrays share storage with the original array, so this is a fast operation which does not require copying data: (setf (aref (make-array 7 :displaced-to *test-grid*) 0) #\!) ;; if i just to :displaced-to it makes linear array of size 7 from index 0 ;; now let's try to take third row (setf (aref (make-array 7 :displaced-to *test-grid* :displaced-index-offset (* 2 7)) 0) #\?) ;; so :displaced-index-offset (* row cols) would get me correct row. and i could iterate over it and write into the array i suppose ;; how do i best loop over array? (let* ((grid *test-grid*) (rownum 2) (rowsize (array-dimension grid 1)) (row (make-array rowsize :displaced-to grid :displaced-index-offset (* rownum rowsize)))) (loop for i from 0 below (array-total-size row) do (setf (aref row i) #\%))) *test-grid* ;; ok. and maybe i'd have to what? wrap grid in class that would translate the BOTTOM & Y into actual ROWNUM ;; ok, next problem - it can't really be infinite height, could need to shift down sometimes? ;; maybe every 1000 check 3 lines and if there's no vertical clearings - shift all down? ;;; GENERIC CODE for figures (defclass figure () ()) ;; maybe only for debugging and printing (defgeneric all-points-from-hook (fig hook)) ; do i need that? (defgeneric check-down-points (fig hook)) (defgeneric check-left-points (fig hook)) (defgeneric check-right-points (fig hook)) (defgeneric get-fig-top (fig hook)) ; for updating TOP (defun points-into-array (points array ch) (loop for (row . col) in points do (setf (aref array row col) ch))) (defmethod resting-into-array ((fig figure) array hook) (declare (type (cons fixnum fixnum) hook)) ; also would like to declare array type (loop for (row . col) in (all-points-from-hook fig hook) do (setf (aref array row col) #\#))) ; save figure points into array. can be common for all figures ;; the figures start with their lovest point 3 units higher than TOP ;; and leftmost point 2 units to the right of left wall ;; so that i guess a good HOOK location ;; how would common code work? 0 .. 6 array ;; - generate hook position: (2 . (top + 3 + 1)) ;; - check down, ;; if move - update hook, maybe update TOP & side-turn ;; else - call finalize into arry; go into same loop for next figure ;; ;; side move - read in direction, select check, apply result of the check to the Y coord of the HOOK ;; if it's DO loop. then what are the VARS: ;; figure, hook, iterations ;; is-resting is exit check, exit Sexp is finalizing TOP and INTO-ARR ;; then next figure loop could continue ;; also DO would count the iterations? could return the iterations, i guess ;; NOPE: we're counting amount of rocks that stopped ;; so, return TOP i guess, or owerwrite TOP that's set up in external LOOP ;; which takes FIGURE from infinite figure looped list ;; ;; ok, i guess ;; let's impelement one figure first, and then generic code. and check that ;;; so, now i could write the generic looping movement down? ;;; hmmm. i could code 2000 size array, but yup. probably should code row calculation immediately ;;; and maybe add ##### flor at the -1 ? ;; oh, come on, let's just make a big array, i have 32Gb of ram, shouldn't that be enough for one time run? (defmethod is-point-free (hook array) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (row . col) hook (and (>= col 0) (>= row 0) (< row (array-dimension array 0)) (< col (array-dimension array 1)) (equal #\. (aref array row col))))) ;; really want to declare also array type (is-point-free '(-1 . 2) *test-grid*) (is-point-free '(0 . 2) *test-grid*) (is-point-free '(9 . 2) *test-grid*) (is-point-free '(1 . 9) *test-grid*) (resting-into-array *test-h-line* *test-grid* '(2 . 1)) (is-point-free '(2 . 0) *test-grid*) (is-point-free '(2 . 1) *test-grid*) (is-point-free '(2 . 2) *test-grid*) (aref *test-grid* 2 2) (equal #\. #\#) (defmethod check-move ((fig figure) array hook direction) (declare (type (cons fixnum fixnum) hook) (type symbol direction)) (let* ((points-to-check (case direction (DOWN (check-down-points fig hook)) (LEFT (check-left-points fig hook)) (RIGHT (check-right-points fig hook)) (t nil))) (can-move (loop for check-point in points-to-check always (is-point-free check-point array)))) (if (not can-move) 0 (case direction (down 1) (left -1) (right 1))))) ;; https://sodocumentation.net/common-lisp/topic/1369/loop--a-common-lisp-macro-for-iteration thanks (defun -check-fig (fig) (let ((hook '(7 . 2))) (init-test-grid) (resting-into-array fig *test-grid* hook) (print-grid *test-grid*) (points-into-array (check-down-points fig hook) *test-grid* #\D) (print-grid *test-grid*) (points-into-array (check-left-points fig hook) *test-grid* #\L) (print-grid *test-grid*) (points-into-array (check-right-points fig hook) *test-grid* #\R) (print-grid *test-grid*) (init-test-grid) )) ;; hook is left point ;;; First figure class Horizontal Line (defclass h-line (figure) ()) (defparameter *test-h-line* (make-instance 'h-line)) (defmethod all-points-from-hook ((fig h-line) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (row . col) hook (list (cons row col) (cons row (1+ col)) (cons row (+ 2 col)) (cons row (+ 3 col))))) (all-points-from-hook *test-h-line* '(1 . 3 )) ;; well, check-down could be a generic method over figure with 'down-check-points' being generic methods specialized for figures. ok, i guess ;; row 0 should be top. The higher row - the lower thing is. (defmethod check-down-points ((fig h-line) hook) (declare (type (cons fixnum fixnum) hook)) (mapcar (lambda (coord) (cons (1+ (car coord)) (cdr coord))) (all-points-from-hook fig hook))) (check-down-points *test-h-line* '(1 . 2)) ;; if DOWN is from zero, then LEFT is also from zero (defmethod check-left-points ((fig h-line) hook) (declare (type (cons fixnum fixnum) hook)) (list (cons (car hook) (1- (cdr hook))))) (check-left-points *test-h-line* '(1 . 2)) ; (ROW . COL) that's quite prone to errors ;; if DOWN is from zero, then RIGHT is to zero (defmethod check-right-points ((fig h-line) hook) (declare (type (cons fixnum fixnum) hook)) (list (cons (car hook) (+ 4 (cdr hook))))) (check-right-points *test-h-line* '(1 . 2)) (defmethod get-fig-top ((fig h-line) hook) (declare (type (cons fixnum fixnum) hook)) (car hook)) ; for updating TOP *test-grid* (resting-into-array *test-h-line* *test-grid* '(0 . 0)) (resting-into-array *test-h-line* *test-grid* '(2 . 0)) ;; (resting-into-array *test-h-line* *test-grid* '(3 . 4)) ;; (defgeneric get-fig-top (fig hook)) ; for updating TOP ;;; now I could try to build a generic inner loop; ;; NEXT classes ;; WHELP. figure appears +4 from lowest point and +2 from leftmost ;; that means that hook for cross would be not a part of figure, but leftbottom corner (defclass cross (figure) ()) (defmethod all-points-from-hook ((fig cross) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 2) . ,(1+ hook-col)) (,(1- hook-row) . ,hook-col) (,(1- hook-row) . ,(1+ hook-col)) (,(1- hook-row) . ,(+ 2 hook-col)) (,hook-row . ,(1+ hook-col)) ) ) ) ; do i need that? (defparameter *test-cross* (make-instance 'cross)) (init-test-grid) (resting-into-array *test-cross* *test-grid* '(2 . 2)) (print-grid *test-grid*) (defmethod check-down-points ((fig cross) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,hook-row . ,hook-col) (,hook-row . ,(+ 2 hook-col)) (,(1+ hook-row) . ,(1+ hook-col)) ) ) ) (defmethod check-left-points ((fig cross) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 2) . ,hook-col) (,(1- hook-row) . ,(1- hook-col)) (,hook-row . ,hook-col) ) ) ) (check-left-points *test-cross* '(18 . 2)) ;; hook:(18 . 2); moveLEFT -> 0 ;; so why is this? (defmethod check-right-points ((fig cross) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 2) . ,(+ 2 hook-col)) (,(1- hook-row) . ,(+ 3 hook-col)) (,hook-row . ,(+ 2 hook-col)) ) ) ) (defmethod get-fig-top ((fig cross) hook) (declare (type (cons fixnum fixnum) hook)) (- (car hook) 2) ; for updating TOP ) (defclass bracket (figure) ()) (defparameter *test-bracket* (make-instance 'bracket)) (defmethod all-points-from-hook ((fig bracket) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 2) . ,(+ 2 hook-col)) (,(- hook-row 1) . ,(+ 2 hook-col)) (,hook-row . ,hook-col)(,hook-row . ,(+ 1 hook-col))(,hook-row . ,(+ 2 hook-col)) ) ) ) ; do i need that? (defmethod check-down-points ((fig bracket) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(+ hook-row 1) . ,hook-col)(,(+ hook-row 1) . ,(+ 1 hook-col))(,(+ hook-row 1) . ,(+ 2 hook-col)) ))) (defmethod check-left-points ((fig bracket) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 2) . ,(+ 1 hook-col)) (,(- hook-row 1) . ,(+ 1 hook-col)) (,hook-row . ,(- hook-col 1)) ))) (defmethod check-right-points ((fig bracket) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 2) . ,(+ 3 hook-col)) (,(- hook-row 1) . ,(+ 3 hook-col)) (,hook-row . ,(+ 3 hook-col)) ))) (defmethod get-fig-top ((fig bracket) hook) (declare (type (cons fixnum fixnum) hook)) (- (car hook) 2) ; for updating TOP ) (defclass v-line (figure) ()) (defparameter *test-v-line* (make-instance 'v-line)) (defmethod all-points-from-hook ((fig v-line) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 3) . ,hook-col) (,(- hook-row 2) . ,hook-col) (,(- hook-row 1) . ,hook-col) (,hook-row . ,hook-col) )) ) ; do i need that? (defmethod check-down-points ((fig v-line) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(+ hook-row 1) . ,hook-col) )) ) (defmethod check-left-points ((fig v-line) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 3) . ,(- hook-col 1)) (,(- hook-row 2) . ,(- hook-col 1)) (,(- hook-row 1) . ,(- hook-col 1)) (,hook-row . ,(- hook-col 1)) )) ) (defmethod check-right-points ((fig v-line) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 3) . ,(+ hook-col 1)) (,(- hook-row 2) . ,(+ hook-col 1)) (,(- hook-row 1) . ,(+ hook-col 1)) (,hook-row . ,(+ hook-col 1)) )) ) (defmethod get-fig-top ((fig v-line) hook) (declare (type (cons fixnum fixnum) hook)) (- (car hook) 3) ; for updating TOP ) ; for updating TOP (defclass square (figure) ()) (defparameter *test-square* (make-instance 'square)) (defmethod all-points-from-hook ((fig square) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 1) . ,hook-col) (,(- hook-row 1) . ,(+ hook-col 1)) (,hook-row . ,hook-col) (,hook-row . ,(+ hook-col 1)) )) ) ; do i need that? (defmethod check-down-points ((fig square) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(+ hook-row 1) . ,hook-col) (,(+ hook-row 1) . ,(+ hook-col 1)) )) ) (defmethod check-left-points ((fig square) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 1) . ,(- hook-col 1)) (,hook-row . ,(- hook-col 1)) )) ) (defmethod check-right-points ((fig square) hook) (declare (type (cons fixnum fixnum) hook)) (destructuring-bind (hook-row . hook-col) hook `( (,(- hook-row 1) . ,(+ hook-col 2)) (,hook-row . ,(+ hook-col 2)) )) ) (defmethod get-fig-top ((fig square) hook) (declare (type (cons fixnum fixnum) hook)) (- (car hook) 1) ; for updating TOP ) ; for updating TOP ;; COPY from above ;; how would common code work? 0 .. 6 array ;; - generate hook position: (2 . (top + 3 + 1)) ;; - check down, ;; if move - update hook, maybe update TOP & side-turn ;; else - call finalize into arry; go into same loop for next figure ;; ;; side move - read in direction, select check, apply result of the check to the Y coord of the HOOK ;; if it's DO loop. then what are the VARS: ;; figure, hook, iterations ;; is-resting is exit check, exit Sexp is finalizing TOP and INTO-ARR ;; then next figure loop could continue ;; also DO would count the iterations? could return the iterations, i guess ;; NOPE: we're counting amount of rocks that stopped ;; so, return TOP i guess, or owerwrite TOP that's set up in external LOOP ;; which takes FIGURE from infinite figure looped list (let* ((grid *test-grid*) (top (1- (array-dimension grid 0))) ; max row with stone, get's smaller. 0 on the TOP (figures (circular (list *test-h-line*))) ;; (fig *test-h-line*) ;; (hook (cons (- top 4) 2)) (lateral-moves (circular '(left right)))) ;; outer loop is simple dotimes for amount of figures we want to drop (dotimes (i 19) ;; let's do simple loop? returning when no longer can move down? ;; move down (let ((hook (cons (- top 4) 2)) (fig (pop figures))) (loop ;; first check lateral move (just after apperaing) (let ((lateral-change (check-move fig grid hook (pop lateral-moves)))) (setq hook (cons (car hook) (+ lateral-change (cdr hook))))) ;; then check if possible to go down (when (= 0 (check-move fig grid hook 'down)) ;; all moves down done, update TOP and exit for next FIG (setq top (min top (get-fig-top fig hook))) (resting-into-array fig grid hook) (return)) ;; more moves down exist ;; do move down, and loop for the lateral change and possible exit (setq hook (cons (1+ (car hook)) (cdr hook))))))) (init-test-grid) (print-grid *test-grid*) *test-grid* (let ((my-list '(1 2 3 4))) `(returning ,(pop my-list) ,my-list)) ;; well it seems to work maybe ok. (defun print-intermediate-step (fig grid hook) (let ((fig-points (all-points-from-hook fig hook))) (points-into-array fig-points grid #\@) (print-grid grid) (points-into-array fig-points grid #\.))) ;; let's generalize this? (defun try-dropping (figures lateral-moves times grid) ;; (print-grid grid) (let* ((top (1- (array-dimension grid 0))) ; max row with stone, get's smaller. 0 on the TOP (percent-index (floor (/ times 100))) (running-percent-index 0)) ;; outer loop is simple dotimes for amount of figures we want to drop (dotimes (i times) (when (= percent-index running-percent-index) (setq running-percent-index 0) (format t "One more: ~a%, , intermediate height: ~a; the step is ~a; the times is ~a~%" (floor (* 100 (/ i times))) top i times) ) (incf running-percent-index) ;; let's do simple loop? returning when no longer can move down? ;; move down (let ((hook (cons (- top 4) 2)) (fig (pop figures))) ;; (print-intermediate-step fig grid hook) (loop ;; first check lateral move (just after apperaing) ;; (print-intermediate-step fig grid hook) (let* ((lat-move (pop lateral-moves)) (lateral-change (check-move fig grid hook lat-move))) (setq hook (cons (car hook) (+ lateral-change (cdr hook)))) ;; (format t "Looping for ~a figure ~a~%hook:~a; move~a -> ~a~%" ;; i fig hook lat-move lateral-change) ) ;; (print-intermediate-step fig grid hook) ;; then check if possible to go down (when (= 0 (check-move fig grid hook 'down)) ;; all moves down done, update TOP and exit for next FIG (setq top (min top (get-fig-top fig hook))) (resting-into-array fig grid hook) (return)) ;; more moves down exist ;; do move down, and loop for the lateral change and possible exit (setq hook (cons (1+ (car hook)) (cdr hook)))))) top) ;; (print-grid grid) ) (init-test-grid) (try-dropping (circular (list *test-h-line*)) (circular '(right left)) 9 *test-grid*) (try-dropping (circular (list *test-h-line*)) (circular '(right)) 9 *test-grid*) (try-dropping (circular (list *test-h-line*)) (circular '(right right left)) 9 *test-grid*) (try-dropping (circular (list *test-cross* *test-h-line*)) (circular '(right right left)) 1 *test-grid*) ;; seems maybe ok. (try-dropping (circular (list *test-cross* *test-h-line*)) (circular '(right left left left left left)) 4 *test-grid*) ;; now to implement the other figures. it's not quite fun (try-dropping (circular (list *test-cross* *test-h-line*)) (circular '(left)) 1 *test-grid*) ; this is not right. no lateral moves done (init-test-grid) (try-dropping (circular (list *test-cross* *test-h-line*)) (circular '(right right left right)) 5 *test-grid*) ; this is not right. no lateral moves done (try-dropping (circular (list *test-cross* *test-h-line*)) (circular '(left left right right right right left right)) 5 *test-grid*) ; this is not right. no lateral moves done ;; this is failure ;; ugh. this is failure. i'd rather take all points and shift them down \ left \ right ;; than do this manually ;; or - have better visual testing. ;; do (put-to-array) for left and for right and for down, and for figure (-check-fig *test-cross*) (-check-fig *test-h-line*) (-check-fig (make-instance 'bracket)) (-check-fig *test-v-line*) (-check-fig *test-square*) ;; ok, with this things would have to be better ;; and with this check fig, could at least visually check 3 other figures (init-test-grid 20) (try-dropping (circular (list *test-cross* *test-h-line* *test-bracket*)) (circular '(left left right right right right left right)) 5 *test-grid*) ; this is not right. no lateral moves done ;; ok, i guess (init-test-grid) (try-dropping (circular (list *test-cross* *test-h-line* *test-bracket* *test-v-line*)) (circular '(left left right right right right left right)) 55 *test-grid*) ; this is not right. no lateral moves done ;; ok, maybe. but overall - ugh. ;; so, run the test data? oh, i havent' yet consumed the data. but it's in few lines, ;; right (defparameter *test-lat-chars* ">>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>") (defparameter *test-lat-symbs* (mapcar (lambda (ch) (case ch (#\< 'LEFT) (#\> 'RIGHT))) (coerce *test-lat-chars* 'list))) (defparameter *shapes-order* (list *test-h-line* *test-cross* *test-bracket* *test-v-line* *test-square*)) (defparameter *endless-shapes* (circular *shapes-order*)) (defparameter *endless-test-laterals* (circular *test-lat-symbs*)) ;; now, i'd want to drop 2022 rocks. in example it should yield 3068 height (typep 1 'fixnum) (init-test-grid 10000) (defparameter *test-run-result* (try-dropping *endless-shapes* *endless-test-laterals* 2022 *test-grid*)) ; this is not right. no lateral moves done (print-grid *test-grid*) ;; ok my 7010 is to be deducted from 10000 (- (array-dimension *test-grid* 0) *test-run-result* 1) ;; well, something is wrong with the square ;; how could i test square without printing intermediate steps? well, i could add that, yeah ;;; let's add per-turn printing as well. (init-test-grid 50) (defparameter *test-run-result* (try-dropping *endless-shapes* *endless-test-laterals* 15 *test-grid*)) ; this is not right. no lateral moves done ;; well, let's run 2022 for my own input? (defparameter *input-lat-chars* (uiop:read-file-string "day17-input.txt")) (length (coerce *input-lat-chars* 'list)) (defparameter *input-lat-symbs* (remove-if-not #'identity (mapcar (lambda (ch) (case ch (#\< 'LEFT) (#\> 'RIGHT))) (coerce *input-lat-chars* 'list)))) (print *input-lat-symbs*) ; cool, it has NIL in the end. why? (defparameter *endless-input-laterals* (circular *input-lat-symbs*)) (type-of *input-lat-symbs*) (typep *input-lat-symbs* 'list) (length *input-lat-symbs* ) (init-test-grid 10000) (defparameter *task-run-result* (try-dropping *endless-shapes* *endless-input-laterals* 2022 *test-grid*)) ; this is not right. no lateral moves done (- (array-dimension *test-grid* 0) *task-run-result* 1) ;; PART 2 ;; In the example above, the tower would be 1514285714288 units tall! ;; How tall will the tower be after 1000000000000 rocks have stopped? ;; so. let's print out intermediate? each 1% ? (init-test-grid 1000000) ;; 866549760 bytes available, 112800000000144 requested. (floor (/ 112800000000144 866549760)) (floor (/ 910721024 1024 1024 1024)) ; available (floor (/ 112800000000144 1024 1024 1024)) ; 105000 iGb requested ;; so, no ;; so, how'd i print report each 1% ? (defparameter *task-2-run-result* 0) (setq *task-2-run-result (try-dropping *endless-shapes* *endless-input-laterals* 2022 *test-grid*)) ; this is not right. no lateral moves done (- (array-dimension *test-grid* 0) *task-2-run-result* 1) (mod 7 4) ;; ok. i'd want to what? maybe every million size truncate? ;; when size get to 1M, get last row (height - 1?) ;; copy that last row to the first, add to the