;; 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. (defun get-ugh-nth (arr n) (let* ((zero-ind (position 0 arr)) (unsafe-index (+ zero-ind n)) (safe-n (mod unsafe-index (length arr)))) (aref arr safe-n))) (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, (defun part-1-ans (filename) (let* ((nums (mapcar #'parse-integer (uiop:read-file-lines filename))) (input-arr (make-array (length nums) :initial-contents nums)) (mixed (mixing-array input-arr))) (+ (get-ugh-nth mixed 1000) (get-ugh-nth mixed 2000) (get-ugh-nth mixed 3000)))) ;; (part-1-ans "day20-test.txt") ;; (print (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 ;; yay, at least previous solution was still incorrect. yayyayay ;;; PART 2. ;; wowy. ;; 1. multiply all numbers by 811589153 ;; 2. do 10 mixings (map 'vector #'1+ (aops:linspace 0 9 10)) (defun part-2-ans (filename) (let* ((data (map 'vector (lambda (zipped) (list (first zipped) (* 811589153 (second zipped)))) (input-arr filename))) ;; (mixed (mixing-array input-arr)) (mixed (do* ((arr data (mixing-array arr)) (iteration 0 (1+ iteration))) ((= 10 iteration) arr)))) (format t "getting part 1, mixed array: ~a~%" mixed) (+ (get-ugh-nth mixed 1000) (get-ugh-nth mixed 2000) (get-ugh-nth mixed 3000)))) (print (part-2-ans "day20-test.txt")) (print (part-2-ans "day20-input.txt"))