;; https://adventofcode.com/2022/day/20 (in-package :day-20) ;; so. how would i do moves in a list? ;; and are there duplicate numbers? ;; it's possible but not sure. ;; also in the input numbers are 4k 5k. ;; i guess on during the moving it would be best to figure out their index? ;; could i insert into list at index? ;; it could be nice to use just cycled list. but. ;; maybe use array? '(1 2 -3 3 -2 0 4) ;; calculating index and then modifying array. is it easy to do shifts on array? ;; and i'd sometimes need to ;; and how multiple passes work with going over self? ;; let's take a break ;; i guess i could copy part of array with the offset arrays ;; ;; the stupid version seems to be 4 cases : ;; - to right inside of array ;; - to right over with overflow ;; - to left inside of array ;; - to left over with overflow ;; but when overflow - could stop to the left or to the right of self. (defparameter *my-arr* (aops:linspace 0 9 10)) ;; imagine i'm displacing 345 by 1 to right ;; ( that would mean 6 moving 3 to the left) (setq *my-arr* (aops:linspace 0 9 10)) (let ((to-be-moved (make-array 3 :displaced-to *my-arr* :displaced-index-offset 3)) (into-these-move (make-array 3 :displaced-to *my-arr* :displaced-index-offset 4))) (loop for i from 2 downto 0 do (setf (aref into-these-move i) (aref to-be-moved i)))) *my-arr* ;; now displacing 345 by 1 to left (setq *my-arr* (aops:linspace 0 9 10)) (let ((to-be-moved (make-array 3 :displaced-to *my-arr* :displaced-index-offset 3)) (into-these-move (make-array 3 :displaced-to *my-arr* :displaced-index-offset 2))) (loop for i from 0 below 3 do (setf (aref into-these-move i) (aref to-be-moved i)))) *my-arr* ;; now let's also remember "moved" element and put it to the "freed up space" ;; moving 6 by 3 to the left (setq *my-arr* (aops:linspace 0 9 10)) (let* ((index-of-moved 6) (moved-value (aref *my-arr* index-of-moved)) (move-by -3) (to-be-moved (make-array 3 :displaced-to *my-arr* :displaced-index-offset (+ index-of-moved move-by))) (into-these-move (make-array 3 :displaced-to *my-arr* :displaced-index-offset (+ index-of-moved move-by 1)))) (loop for i from 2 downto 0 do (setf (aref into-these-move i) (aref to-be-moved i))) (setf (aref *my-arr* (+ index-of-moved move-by)) moved-value)) *my-arr* ;; ok. but these 2 downto 0 || 0 to 2 dependent on -3 +3 and that's ugh ;; moving 2 by 3 to the right (now displacing 345 by 1 to left) (setq *my-arr* (aops:linspace 0 9 10)) (let* ((index-of-moved 2) (moved-value (aref *my-arr* index-of-moved)) (move-by 3) (to-be-moved (make-array 3 :displaced-to *my-arr* :displaced-index-offset (+ index-of-moved 1))) (into-these-move (make-array 3 :displaced-to *my-arr* :displaced-index-offset index-of-moved))) (loop for i from 0 to 2 do (setf (aref into-these-move i) (aref to-be-moved i))) (setf (aref *my-arr* (+ index-of-moved move-by)) moved-value)) *my-arr* ;; so also difference in displaced indexes. ;; shift to LEFT (move item left): ;; ;; shift to RIGHT (move item right): ;; well, i could just save this code as two separate functions ;; would be nice to immediately start doing the repeatable tests (move-item-to-left (aops:linspace 0 9 10) 6 6) ;; and a separate function for swithing to the right? (move-item-to-right (aops:linspace 0 9 10) 6 1) (move-item-to-right (aops:linspace 0 9 10) 6 2) (move-item-to-right (aops:linspace 0 9 10) 6 3) ;; next what? calculation of the target index through modulo '(1 2 3 4 5 6 7 8 9) ;; if we're moving 2 by -2 how does that work? ;; we have starting index 1, we have length 9. ;; my guess is that take MOD by 9-1 ;; how many swaps to the right until the element returns to its original place? '(1 2 3 4 5 6 7 8 9) '(2 1 3 4 5 6 7 8 9) '(1 3 4 5 6 7 8 9 2) '(1 3 4 5 6 7 8 2 9) '(1 3 4 5 6 7 2 8 9) '(1 3 4 5 6 2 7 8 9) '(1 3 4 5 2 6 7 8 9) '(1 3 4 2 5 6 7 8 9) '(1 3 2 4 5 6 7 8 9) '(1 2 3 4 5 6 7 8 9) ;; so, if moving by 9. hm ;; then moving by 12 is 9 + 3 (mod 9 3) (mod 10 3) (length (make-array 7)) (move-item-to-left (aops:linspace 0 9 10) 6 9) ;; ok, now join into one function that moves the element by it's value? (find 4 '(1 4 3 2 9)) (position 4 '(1 4 3 2 9)) (defparameter *test-array* (make-array 7 :initial-contents '(1 2 -3 3 -2 0 4))) *test-array* (move-elem-by-itself *test-array* -2) ;; whelp. my movements are ugh. ;; so. "i'd want additional move on top of my move-left and move-right"? (mod -1 3) (move-item *test-array* 3 3) (move-item *test-array* 3 4) (defparameter *test-array* (make-array 7 :initial-contents '(1 2 -3 3 -2 0 4))) *test-array* (move-elem-by-itself *test-array* -2) ;; this seems to work. ;; now back to the loop? (defparameter *test-array* (make-array 7 :initial-contents '(1 2 -3 3 -2 0 4))) (mixing-array *test-array*) ;; after moving 2, arr: #(1 -3 2 3 -2 0 4) ;; after moving -3, arr: #(1 2 3 -2 0 -3 4) ;; -3 move wasn't correct (loop for elem across *test-array* do (print elem)) (defparameter *test-array* (make-array 7 :initial-contents '(1 -3 2 3 -2 0 4))) (move-elem-by-itself *test-array* -3) ;; 0 -> 0 ;; -1 -> (len - 1) ;; -2 -> (len - 2) (mod -1 7) ;; so, just hack it? when we move to the left, we add one more? ;; so, ugh and when moving to positive, but going over the what ;; the number is not "switched" with the neighbor, it's jumping over the neighbor... ;; so, if we go to 0 or to len-1 then we jump to the other side? (defparameter *test-array* (make-array 7 :initial-contents '(1 -3 3 -2 2 0 4))) (move-elem-by-itself *test-array* 2) (defparameter *test-array* (make-array 7 :initial-contents '(1 -3 3 -2 2 4 0))) (move-elem-by-itself *test-array* 4) (defparameter *test-array* (make-array 7 :initial-contents '(1 2 -3 0 3 4 -2))) (move-item *test-array* 5 4) (move-elem-by-itself *test-array* 4) ;; now this incorrect: ;; after moving 3, arr: #(1 2 -2 -3 0 3 4) ;; after moving -2, arr: #(-2 1 2 -3 0 3 4) ;; -2 should have went instead of to 0 straight to the end. so ;; ;; and now it works ;; god i also need to take 1000th value with overbound. ugh. (get-ugh-nth (mixing-array *test-array*) 1000) (get-ugh-nth (mixing-array *test-array*) 2000) (get-ugh-nth (mixing-array *test-array*) 3000) ;; uh. after the value 0... ;; so first find index of 0 (let* ((nums (mapcar #'parse-integer (uiop:read-file-lines "day20-input.txt"))) (input-arr (make-array (length nums) :initial-contents nums)) (mixed (mixing-array input-arr))) (+ (get-ugh-nth (mixing-array mixed) 1000) (get-ugh-nth (mixing-array mixed) 2000) (get-ugh-nth (mixing-array mixed) 3000))) ;; 1797 is too low, (part-1-ans "day20-test.txt") (part-1-ans "day20-input.txt") ;; well, do we have duplicates? (ql:quickload :fset) (fset:set 1 2 3) (fset:set '(1 2 3)) (print (let* ((nums (mapcar #'parse-integer (uiop:read-file-lines "day20-input.txt"))) (input-arr (make-array (length nums) :initial-contents nums)) (input-set (fset:convert 'fset:set nums)) ) (list 'arr (length input-arr) 'set (fset:size input-set)) )) ;; (ARR 5000 SET 3613) ;; well, yupikayey ;; how should i be doint that? ;; AND i should have checked that from the start. ;; so. there are duplicates. (fset:convert 'fset:bag '(1 2 3 2 4 5)) ;; what should i do about the duplicates? ;; i'd need to store elements with their initial indexes i suppose ;; and then what? iterate not over initial collection, but just over "initial" indexes ;; so, how'd i do that? ;; #'move-item works with index and move-by ;; so shouldn't depent on type of elements ;; so just #'move-elem-by-itself should take in "original index" ;; then find position in the array by the index. ;; and array would be (index value) (zip-with-index '(2 14 1 3 5)) (input-arr "day20-test.txt") (mixing-array (input-arr "day20-test.txt")) ;; and it works, now. ;; ;; next - extract the values from the 1000th etc ;; wait what. why did i do the mixing again. ugh ;; was that the problem, not the duplicates? will revert after getting to the answer, ;; but yikes ;; oh, i need to find 0 by value in new array (part-1-ans "day20-test.txt") (part-1-ans "day20-input.txt") ;; and i get a gold star. ;; let's commit and try with revert?