From ae745dc0f2d213ee9eecff31111082655d22149b Mon Sep 17 00:00:00 2001 From: efim Date: Sun, 18 Dec 2022 17:22:43 +0000 Subject: [PATCH] day 17 part 1. ugh --- day17-input.txt | 1 + day17-scratch.lisp | 700 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 701 insertions(+) create mode 100644 day17-input.txt create mode 100644 day17-scratch.lisp diff --git a/day17-input.txt b/day17-input.txt new file mode 100644 index 0000000..ff8e775 --- /dev/null +++ b/day17-input.txt @@ -0,0 +1 @@ +><<<<><<>>><<<>>><<><<>>>><<><<>><><<<<>>>><<>>><<<>>>><<<<><<<<>>>><>>>><>>><<><>><<>><<<<>><<><<><>><<><>>><<<>><>>><<>><<>>><<<><>>><<>>><<<<>><<<<><<<><<>>><<<>>><>>><<<>>><<<<>>>><<<>>><<<>><<<<>><<<>>><<<>>><<>><<>><<<>><>><<<><<>><<<>>>><>>>><>><<>>>><<<<><<<<><<<<><<>>>><<<>>>><<<><<>>><<<><><<>><<>>><<>><>>><<>><<>>>><<<<><<<>>><<>>>><<>>>><<>><>>><<<<>>><<<>><<<<><>>><>><<<<>>><<>>><><<<>>><<<><<<>><<<<>>>><<<><<<><<>>>><<<>>><<><<>>>><<<<>><<>><<<<>>>><<<><<>>><<<<>>>><<<<>>>><<<<>><><>><<>>>><>>>><<<<>><>>><<<<>>><><<><<<>>>><><<<>><<>>><<<>>><<<>><<<><<>><<><<>>>><<>>><<<<><<<<><>>>><<>><<>>><<<>>>><<<<>>>><<<>>>><<>><>>>><><<<>>>><<<<><>>><>>><<>>>><>>><<<<><<>>><<<<><<>>><<>><<<>><<<<>>><<>>><<<>>><>>><<<<><>>><><<<<>>><>>><<<<><><<<<>>>><<>>><<<<>>><<<<>>>><>>>><<><<<<>>><<<<>><<<<>><<>><<<<>>>><<<>>>><<<<>>><>>>><<<<>><<<<>><<>>>><<<><<<>>>><<><<<<>>>><><<<<>><>><<>>>><<<<>>><<>>><<>>><<<>>>><>>><<<<>>>><>>><<>><<><<>><<><<><<<>>><>><<<>><<<><<<<><<<<>><<>><<<<>>>><<<<><<<<>>>><<><<><<<<>><<<>>><>>><<<<><><>><<>>><<><>>><<<>><<<<><<<<>>><<<>>>><<>><<><<<<>><<<<>>><<>><<>><<<<><>>>><><<>>>><>>><<<><>><<>>>><>>><<<<><<<<>>><<<>>><<<>>>><<<<><<<<>>>><<><<<<>>><<<>><<>>>><<>>><<>><<><<<<>>><<>><<><<<<>>><<<><<<<>>><<>>>><<<<>><>>>><<<<>>><<>>><<><<>><<<>>><<<<>>>><<<<>><<><<>><<<<>>>><><<<><><<<><<<><<<<>><>><<<>>><><<<><<<<><<<>><>>><<>><>>><<>><<>><><>>>><<<><>>><<>>>><<<>><<<>><<<<>>><<<<>>><<<<>>>><>><<<>><<>><<<><<>>>><>><<<><<<<>>><<><<<<>><<>>><<<<>>>><<<>>>><>>><<<>>><<<>>><<>><<<<>>>><<<<><><<<<>>>><<<>><<<<><<<<>>><<<<>>>><<>>><<<<>>>><<<<><<<><>>>><<>>>><<<<>><<<>>>><<<<>><<>>>><>><>>>><<<>><<>>>><<<>>>><<>><<<>>>><<<>><>><><<><>><>><<<>><<<>>><<>>><<<<>>><<<><<>>><<<<><>>>><<><>>>><<><<<>>>><><<<<>>><<<<>><<>>>><<<><<<>><<><>>><<>>>><<><>>>><<<<><>><<>><<<>>><>><<<>><<<<>>><<<<>><>><<><<<<><<<>>><><>>><<>>>><<><<<<>>><<>>><<<><<>>><><<<><>>><<><<<>>><<>>><<><<><<<<>>><<><<<<>><<<<>><>>>><<<<><>>>><<<<>>>><<>><<<<>>>><<<<><<<>>><<<<>>><<<<><<<><<>><>>>><>>><<<>>>><<<<>>><<<>><<<<>>>><<<>>><<<<>>><<<<>>><<<>>><<>><<<>><<<<>><<<<>>>><<>><<>><>>><<<<>>><<<<>>><<<<><<>>><><<<<>><<>>>><<><<>>><>><<<><>>><<<<><<>><<>>><><<>>><<<<><<<<><>>>><<>>><<>>>><<<>>><<>>><<<<>>><<>>>><>><><<<<>>>><>>><<<><<<<>>><<><<>>>><<<<>>>><>><>><<<>>>><>><><<>>><<<<><<<>>><<>>><><<>>>><<>>>><<<><<<>>><<<><<<>>><<<><<>>><<<<>><<<>><>>><>><<<<>>>><><<<<>>>><><<<<>>>><<<>>>><<>><<<>>><<<<>>>><<<>><<><>>>><<<>>><<<<><<<>>><<<>>><<>><<>>>><<>>><>><<<>>>><<>>>><<<><<>>><<<>><><<>>><<<<>>>><<<><<>>><>><>>>><><>>><><<<<>><<<><>>>><>><<<>><>>><<<><<><><<>><<<>>>><<<<>>>><>>>><<<><<<>><>>>><<>>>><<<>>><<><<<<><<<<>><<<>><<>>><<><><<<<>>><>>>><<<><>><<><>><>>>><><>>><<><<>><<<>>>><<>><<><<<><><<<>>>><<<<>><<<<>>><<<<>>>><>>><<<<><<>>>><><<>>><<<<>><<<>><<<>>>><><<<>><<<<><<<><<>>>><<<>>>><<<<>>><<<>>>><<<<>><<<>>><<<>>><>>>><<<<><<<<>><>>>><<>><<<<>>><<<<><<<<><<<<><<<<>>><<<>><<<>><<>>>><>><<<<><<><<>>><<>>>><<<><>><<<<><<<>>>><<<<><>><<<>>>><<<<>>>><<<>><<<><<<>>>><<>>>><<<>><><<<<>>>><<>>>><<<>>><>>>><<<<>><<<<>><>>><<<<>>><>>>><<<<>>><<>>><<<>>><<<>>><<<<>>><<<<>>>><<<<>><<<<>><>>><<<<>>><<<>>><<>><<<<><<>>><>>>><<<>>><<>>><<><<<>>>><<<>>><<>>>><<>>><><<<<>><>>>><>>><>>>><<<>><<>><<<<><<<><>><<<<>>>><<<><<>><<<<>><<>><<>><<>>><<<<>>><<<<><<<>>><>><>>>><<<>>><>>>><<<<>><<<<>><>>>><<>>><<<<>>><<>>><<<<><>>>><>><><<<<>><>>><<<<>><<<<>>>><<<>>>><<<<>><<<<><<<<>>><>>><<<<>><<<><<<><><<<>>><<>>>><<<<><<<<>>><<<<><<>>><<<>>><<<<>>>><<<>>><<<<><<><<>>>><>>>><<<<>>><<<<>>>><<>>>><<<>><<<<>><<>>>><<<>>>><<<<>>><<<<>>><<<><<><<<<>>>><<><<><>>>><<<>>><<<<>>><>><>>>><<<<>><<<>>>><<<>><>>><<>><>><<<<>>>><><<<>>>><<>>>><<<<><<<>>><<<<>><<<<>>>><<<><<<>><<>><<<>>>><<<>><>>>><<>>>><<<>><>><>>>><<<>>><<<<>>>><>><<>><><>>><<<<><<>><>><>>><<>><>><<<><<>>>><<>>>><<<>>>><<>>>><><<>>>><<<>><<<<>><<<<><<<<>>>><>>>><><>>><<<<>>>><<<>><<<>>><<<<>>><<><<<>>>><>>><>>><<<>>><<<><>>><<<><<<>>>><<>>><<<<>><<<<>><<<>><<<<>>><<<<>>>><<<<>>>><>>>><><<<<>><<<<>><<<<>>><<<<>>>><>>><<>><>>><>>>><>>><<<><>><>>><><>>><>><>>>><<<<>><<<>>>><<<>>><<<<>><<<<>>><>><><<<<>><<>><<<><<>><<<<>>><<<>><>><>><<><<<>>>><<<<>><<<<><<<<><<<>>>><<><<<<>><<<>>><<><<><>>><<>><<>>>><<<>><<>><>><<>><<<>>>><>>>><><>>>><<<<>>>><<>>>><<>>>><<<<><<>><><<<<>>><<>>>><<<<>>><>>>><<<>>>><<<>><<>>><<>>><<<>>><<<<>>><<><<<<><<<<>>><<>>><<<<>>><<<>>>><<<<>><<<<>>>><<<<>>>><<><>><<>>><<>><<<>>>><>>><>><<<<>>><>><<<<>>>><<<<>><><<<><>>>><><<>>><<<<>><<<<>>><>><>>><<<>>><><<<<>>><>>><<<<>>><>>><<<>><>>>><><<<<>>>><<<<>><<<><<<>><<<>>><<<>>><<>>><>>><<<<>><>>><>>><<<>><<>>><<><<<<>><>>>><>>>><<<>><><>>><<<><>><<<>>>><<>>><<<<>>>><<>>><<<<>><<<<>>>><<<<>>>><<>>><>>>><<<<>>>><<<>>>><<<<>>><<>><><>>><<<>>>><<>>>><>>><<<<>>><<>>><<>>><<<>><>>><>>><<><<<><<<><>><><>>>><<<>>>><<<<>>>><>>><<<>>><<<<>><<<<><<>>><<>>>><<<<>>><<<<>>>><<>><<<<>>><<<<>><<<>>><<>>>><<>>>><<<<>>><<>><>><>><>><<<>>>><<<<>>>><<<>>>><<<<>>>><<<<><<<>><<<>><<<><<>>><<<>><>><<>>><<<><<><<<>>><<<<>><><<>>><<>>>><<><<<>>>><><<<>>>><<<<>><<<>>>><<>>><<<<>>><<<<>>><<<<>>>><<>>>><<><<<<>><<><<>>>><<><<>>><<<>>>><<>>><<<<>>><<<>>><<>>>><<<>>>><<<<>>><<<<>>><<<<>>><<><<>>><<<<>><<<<>>><<<><<<>>>><<<<>>>><<><><<>>><<<<><<<>>>><<<>>>><<<<>>><>>><<>>>><>><<<<>>><<<<>>>><<>><<<<>>><<<>>>><<<>>>><<<<>><>>>><<<<>>>><<<>><>>><<<<><<<>>><<<<>>>><<<<>>><<>>>><<>>>><<<>>><<<<>><>>><<<<>><<<<>>>><>><<<>>>><<><<>>>><<<>>><<><>>>><<<>>><<<>>>><<<<><<<>><<<<><<<>>>><<<<>>>><<<>>>><<<>>><>>>><<<><>>><<<<><<<><>><>><>><<<<>>><<><<<>>><<>><<<<>>><<<<>>><<<<>>><<><<<<>>>><<>>><<<>><<<>><>><<<>>>><>>>><<<<>><<><<<>><<<<>><<>>><<<>>>><<<><><<<>>><><<<<>>><<>><<>><>><<<<>><<<<><>>>><><>>>><<<><<><<<>>><>>><<<>>><<<<><<<<><><<><<>><<>><<<<>>><>>>><<<<>><<><>><>>><>>>><<<>>><<><>><<<<><>>>><>>>><>>>><<>>>><<<>>><<>>><<<>>><>>>><<>><<>><<<<>>>><<<>>><<>><>><<<>>>><>>><<<>>><<<>>><<<<>>>><<><>><<<>>><<<>>>><>>><<><>><<<<>><<<<>>>><<<<>>>><<<>><<<<><>>>><<><><<>><>><><>>>><<<>><<<<><<<<><><><>>><>><<<<>>>><<>>>><>>>><<>><>>>><<<<>><<<<>>><><<<>><>>>><>>>><<>>>><<<<>>>><><<<<><><<<<><<<<><<<>><<<>>>><<<<>>>><>>>><<<<>><<>>>><<<<>>>><>>><<<>>>><<><>>><<<<>>>><<><<><<<>><>><<><<>><<<<>>>><>>>><<>>><<<<>>><>>>><<<>>><<<>><<<><<<><>>><>><>><<<>>>><<<<><>>>><<<<><<<<><<>>><<<>>><<<>><>>><<<>><<<>><<><<<<>><<<>>>><<<>>>><>>><<<>>>><>>>><<<><<>><>><<<<><>>>><<<<>><>>>><<<><<<<><>>><<<<>>>><<<<>>>><<<>><>><<<>>><<<><<<<>><<><>>><<>>>><>><><<<<>>>><<<<>>><<>><<><<<<><<<<>>><<<>><<><<><>>>><>><<<<><<<><<<<>><<<<>><<<>><<><<<<><<<>>>><<><<<<>><<<<>>>><>>><<<<><<<>>><>>>><>>>><<<>>>><<>>>><<>>><<>>>><<>><<<<>>><<<>>><<<<>><<><<>>>><>><<>>>><<<<><<<>>>><<<>>>><<<>>>><<<><<<>><>>><<<<>>><<>><<<><<>>>><<<><<>>>><<<<>><<<<>><>><><<<>><<>>>><<<>><<<<>>><<<><<<<><<<>>><<<><<<<>>>><<>>>><>><<<<>>><><<<>>><<>>>><<<<><<>><<>>><>><<<>>>><<<<>>>><<>>>><<<<><><<<<>><><>><>><<>>><<>>><<><<<><><<<><><<>>><<<<>>>><<<>>><<<>><<<<>><<<>>><<<<><>>>><<>>>><<<<><<<>><<<>>>><<>><<>>>><<<>><<><<<>>>><>>><<<>>>><<>><<<<>>><<>><<<<><<>>><<<<>>>><>>>><<<>>><>><>>>><>>>><<>>><>>>><>>><<>>><<>>><<<>>><<<<>><>>>><<><<>>><<<>>>><<<<>>><<<><<<>>><<<>>><<>><>>><><<<><<>>><<>><<<>><<>>>><<>>>><>>>><<<>>><<<>>>><<<<>>>><><<<<>><<<>><<><<<<>><<<<><>>><>><>>><>>>><<>>><>>><<<<><<<<><<<>><>>>><>><<>>><><<<>>>><<<>>>><>>>><<<<>>><<<<>>>><<<>>><<<><>>>><><<<>><>>>><<><<<><<<>>><<>>><>>><<<<>>>><<><<<<>>>><<>>><<<<>>>><<<><<<<><>>><<<><>>><<<<>>><<<<><><<<<>><<<>><<<<><<<>><>>><>><<>>>><<>>><<<<>>><>>><<><<<<>>><>><<<<>>><><><<>>>><<<>>>><<>>>><<<<><>>>><<<<>><<>>>><>><<<>>><<>><>>><<<><<<>><<<><<>>><>>><<><<>><<<<><<>>>><<>>>><<<>>><<<<>><<<>><<<>>><<<>><<<<>>><<<<><><<<><><<<>><><>>>><>>>><<<><<<><<<<><<<>>>><<>><>>>><<<<>>>><>><<<<>>><>>>><<<><<<>>>><<<>>><><<<>>>><<<>>><<<<>>><>>><<<<><<<>><<<><><<<>><<><>>>><<>><<>>><<>><<<><>>>><<>><<<>><<>><>>><<<><<<<>>><<>>>><<>>><<<<>>><>>>><<<<>>><<<<>>><<>>><<>>>><<<<><>><<<>>><<<>>><>><<>>><><>><<>>><<<<>><<<<><<<<>>><<<<>>><<>>>><<<<>>>><>>><<<<><<>>>><<>>><>><<<<><<<<>>><<>>><<<<>>><<<><<>><<<<>>><>>>><<<>>>><<>><>><<<><<<>>>><<>>><<<<>>>><<<<>><<<<>>>><<<>>>><<>>><<<<>>><<<>>>><<>>><><>>>><<<<>>><<<<>>><<<>>>><<<<>>>><>>>><<>>>><><<>><>>>><<<<>>><<<<><<<>><>><<>>>><<>><>>><<>><<>>><<>>><<>>>><<<<>><<<<>><<<<>>>><<<<>>>><<>><<<><<>>><<>>><<<<>>><>>>><<><>><><>>><<<>><<<<>>>><<>><<<><<<>>><<<<>>><<>>>><<>><<<>>><<>>>><<>><<>>><<<<>><<<<>><<<><<<>>>><<<>>><<<<>><>><>>><>>>><>>>><<>>>><>>><<<>>><<><>>>><<<<>>><<<>><<<<>><<><>>>><<<<><<><>>><<<<>><<<<>>><<<><<><<<>><>>>><<<<>><<<<>>>><<<>>><><<>>>><<><><<>>><<<<>><<<<>>><>>>><<<>><<<<>>>><<<>>><<<<>>>><<><<<>>><<>>><<<><><<<<><><<>><<<<>>>><<<<>><<<<><<>>>><>><>><<>>>><>>>><<<<>><><<<>><<<>>>><<><<>><<<<>><<><>>>><<<<>><<>><<<>>><>>>><<<<><<<<>><<<><<>>>><<<><<<>>>><<>>>><<<<><>>><<<>>>><<<<>>>><>><>>>><<<>><<>>>><<<>>>><>>>><<<<>>>><<<<>>><<<><<><<<<>><>>>><<<>>><<>><<<<>>><<<<>><>><>>>><>>>><<>><>>>><<<<>>><>>><<<<>><<><<<>>><<>>>><<<<>>>><><><<<>>><<<<><<<<>><<><<<<>><<<>>><<><<<<>>>><<<<>><>><>><><><<><>><<<<>>><<><<<>>><<><<>>>><<<><<<<><<<<><<>>><>>><<>>><<>>>><<><<<<>>>><><<><<>>><><<<<>><>>><><<<<>>><<<<>><<<>>>><<<<><<<>><<<>><<><><<<>><<<>>>><<<><<<><>>><<<<>>><<>><<<>>><<<>>><<<><<><<<<>>><<<><>>>><<><<<>>><>>><<<>>><<<>>>><<<>>><<<>>>><<<><<>>><<>><<<>>>><<<<>><<<<><><<<<>><<>><<<>>><<<>><<<>>><<<<>><<>><>><<<><<>>><<<>>><>>><<<>>><<<>><<<>>>><<<<>><<>><<>><><<<>><<<<>>><<<>>><<<<><>>><<<<>><<<<>>>><<<>>><<<<>><<>>><<>>><<<>>><<<>><<>>>><><<>>>><><<>>><><<<<>>>><<<<>><>><<<<>>><<<>><<<><<>>><<<<><>>><>>><<>>>><<><<<>><<<>>><<<>>><<<>><<>><<><<<<><<<<>>><<<><<<<><<<<><<<><<<><>>><<>>>><>>>><>>><<><<<<><<<>>><<<>>><<><<<<>>>><<<<>>>><<>>>><<>>>><<<<><<>><>><<<><><><>><<<>><<<<>>>><<<<>><<<<>>><<><<<<>><<><>>><<<>><<<><<<<>><><<<<><<<>>><>>><<>>><<>>>><><<>><>>>><<<<><<<<><<><<<>><<<>>>><<>><<>>>><<<<>><<<>><<<><<>><<>>><<>>><<>>><<>>>><<>>><<<<>>><<><<<<>><>><<<><<<>>><<>>>><<<>><>>><<><<<<>>>><>>>><<><>>><<<<><<<><>>>><<<<>>>><<<><>><<<<><<<>>>><<<><<<<>>><<<>><><>><>>>><<<<>>>><>><<<<>>><<>><<<<><<>>>><<<<>><>>><>><<<>>>><>><<<><><<>>>><<<>><<>><>><<><<>><>>><>>><<><><<>>>><<>>>><>>><<>>>><>>< diff --git a/day17-scratch.lisp b/day17-scratch.lisp new file mode 100644 index 0000000..c48271c --- /dev/null +++ b/day17-scratch.lisp @@ -0,0 +1,700 @@ + +;; 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