day 20 kicking me with duplicates
This commit is contained in:
parent
2eb4b5c0a5
commit
974cc4993d
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,241 @@
|
||||||
|
;; 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 (mixing-array mixed) 1000)
|
||||||
|
(get-ugh-nth (mixing-array mixed) 2000)
|
||||||
|
(get-ugh-nth (mixing-array mixed) 3000))))
|
||||||
|
|
||||||
|
(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
|
|
@ -0,0 +1,7 @@
|
||||||
|
1
|
||||||
|
2
|
||||||
|
-3
|
||||||
|
3
|
||||||
|
-2
|
||||||
|
0
|
||||||
|
4
|
|
@ -0,0 +1,112 @@
|
||||||
|
;; https://adventofcode.com/2022/day/20
|
||||||
|
|
||||||
|
(defpackage :day-20
|
||||||
|
(:use :cl))
|
||||||
|
(in-package :day-20)
|
||||||
|
|
||||||
|
(ql:quickload :array-operations)
|
||||||
|
(ql:quickload "fiveam")
|
||||||
|
(ql:quickload 'alexandria)
|
||||||
|
|
||||||
|
(5am:def-suite day20-tests)
|
||||||
|
|
||||||
|
;; and shift some slice 1 to right
|
||||||
|
(defun move-item-to-left (array moved-index move-size)
|
||||||
|
(declare (optimize (debug 3)))
|
||||||
|
(let* ((move-size (mod move-size (1- (length array))))
|
||||||
|
(moved-value (aref array moved-index))
|
||||||
|
(move-by (- (mod move-size (length array))))
|
||||||
|
(moving-slice-size move-size)
|
||||||
|
(to-be-moved (make-array moving-slice-size :displaced-to array
|
||||||
|
:displaced-index-offset (+ moved-index move-by)))
|
||||||
|
(into-these-move (make-array moving-slice-size :displaced-to array
|
||||||
|
:displaced-index-offset (+ moved-index move-by 1))))
|
||||||
|
(loop
|
||||||
|
for i from (1- move-size) downto 0
|
||||||
|
do (setf (aref into-these-move i)
|
||||||
|
(aref to-be-moved i)))
|
||||||
|
(setf (aref array (+ moved-index move-by)) moved-value)
|
||||||
|
array))
|
||||||
|
|
||||||
|
(5am:def-test move-left-inside-of-array (:suite day20-tests)
|
||||||
|
(5am:is (equalp (make-array 10 :initial-contents '(0 1 2 6 3 4 5 7 8 9))
|
||||||
|
(move-item-to-left (aops:linspace 0 9 10) 6 3))))
|
||||||
|
(5am:def-test move-left-to-edge (:suite day20-tests)
|
||||||
|
(5am:is (equalp (make-array 10 :initial-contents '(6 0 1 2 3 4 5 7 8 9))
|
||||||
|
(move-item-to-left (aops:linspace 0 9 10) 6 6))))
|
||||||
|
(5am:def-test move-by-arr-size-leaves-intact (:suite day20-tests)
|
||||||
|
(5am:is (equalp (make-array 10 :initial-contents '(0 1 2 3 4 5 6 7 8 9))
|
||||||
|
(move-item-to-left (aops:linspace 0 9 10) 6 9))))
|
||||||
|
(5am:def-test move-by-more-than-arr-size (:suite day20-tests)
|
||||||
|
(5am:is (equalp (make-array 10 :initial-contents '(0 1 2 6 3 4 5 7 8 9))
|
||||||
|
(move-item-to-left (aops:linspace 0 9 10) 6 12))))
|
||||||
|
|
||||||
|
(defun move-item-to-right (array moved-index move-by)
|
||||||
|
(declare (optimize (debug 3)))
|
||||||
|
(let* ((move-by (mod move-by (1- (length array))))
|
||||||
|
(moved-value (aref array moved-index))
|
||||||
|
(moving-slice-size move-by)
|
||||||
|
(to-be-moved (make-array moving-slice-size
|
||||||
|
:displaced-to array
|
||||||
|
:displaced-index-offset (+ moved-index 1)))
|
||||||
|
(into-these-move (make-array moving-slice-size
|
||||||
|
:displaced-to array
|
||||||
|
:displaced-index-offset moved-index)))
|
||||||
|
(loop
|
||||||
|
for i from 0 below move-by
|
||||||
|
do (setf (aref into-these-move i)
|
||||||
|
(aref to-be-moved i)))
|
||||||
|
(setf (aref array (+ moved-index move-by)) moved-value)
|
||||||
|
array))
|
||||||
|
|
||||||
|
(5am:def-test move-right-inside-of-array (:suite day20-tests)
|
||||||
|
(5am:is (equalp (make-array 10 :initial-contents '(0 1 2 3 4 5 7 6 8 9))
|
||||||
|
(move-item-to-right (aops:linspace 0 9 10) 6 1))))
|
||||||
|
(5am:def-test move-right-to-edge (:suite day20-tests)
|
||||||
|
(5am:is (equalp (make-array 10 :initial-contents '(0 1 2 3 4 5 7 8 9 6))
|
||||||
|
(move-item-to-right (aops:linspace 0 9 10) 6 3))))
|
||||||
|
(5am:def-test move-right-by-arr-size-leaves-intact (:suite day20-tests)
|
||||||
|
(5am:is (equalp (make-array 10 :initial-contents '(0 1 2 3 4 5 6 7 8 9))
|
||||||
|
(move-item-to-right (aops:linspace 0 9 10) 6 9))))
|
||||||
|
(5am:def-test move-right-by-more-than-arr-size (:suite day20-tests)
|
||||||
|
(5am:is (equalp (make-array 10 :initial-contents '(0 1 2 3 4 5 7 8 9 6))
|
||||||
|
(move-item-to-right (aops:linspace 0 9 10) 6 12))))
|
||||||
|
|
||||||
|
(defun move-item (array move-index move-by)
|
||||||
|
(let* ((raw-target-index (if (>= move-by 0)
|
||||||
|
(+ move-index move-by)
|
||||||
|
(+ move-index move-by)))
|
||||||
|
(in-array-target-index (mod raw-target-index (1- (length array))))
|
||||||
|
(in-array-target-index (if (= 0 in-array-target-index)
|
||||||
|
(1- (length array))
|
||||||
|
in-array-target-index ; a hack
|
||||||
|
))
|
||||||
|
(safe-move-by (- in-array-target-index move-index)))
|
||||||
|
;; (list move-index move-by
|
||||||
|
;; 'raw-target raw-target-index
|
||||||
|
;; 'in-array-target in-array-target-index
|
||||||
|
;; 'safe-move-by safe-move-by)
|
||||||
|
(if (> safe-move-by 0)
|
||||||
|
(move-item-to-right array move-index safe-move-by)
|
||||||
|
(move-item-to-left array move-index (- safe-move-by)))
|
||||||
|
))
|
||||||
|
|
||||||
|
;; we know the element value, but not it's place
|
||||||
|
(defun move-elem-by-itself (array element)
|
||||||
|
(declare (optimize (debug 3)))
|
||||||
|
(let ((i (position element array)))
|
||||||
|
(move-item array i element)))
|
||||||
|
|
||||||
|
(defun mixing-array (arr)
|
||||||
|
(let ((to-be-modified (alexandria:copy-array arr)))
|
||||||
|
(loop
|
||||||
|
for elem across arr
|
||||||
|
do (progn (move-elem-by-itself to-be-modified elem)
|
||||||
|
(format t "after moving ~a, arr: ~a~%" elem to-be-modified)
|
||||||
|
))
|
||||||
|
to-be-modified))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(5am:run! 'day20-tests)
|
Loading…
Reference in New Issue