aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2023/day06
Commit message (Expand)AuthorAgeFilesLines
* solution part 2Oscar Najera2023-12-061-3/+21
* [AoC2023] day06 lisp part 1Oscar Najera2023-12-062-0/+42
id='n29' href='#n29'>29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
(ql:quickload '(fiveam uiop))

(defparameter *msg* #(1 2 -3 3 -2 0 4))

(defun directional-pointers (size)
  (let ((forward (make-array size))
        (reverse (make-array size)))
    (dotimes (i size)
      (setf (svref forward i) (mod (1+ i) size)
            (svref reverse i) (mod (1- i) size)))
    (values forward reverse)))

(defun follow-pointer (pointer index count)
  (if (zerop count)
      index
      (follow-pointer pointer (svref pointer index) (1- count))))

(defun move! (forward reverse element-idx shift)
  "FORWARD is the leading array, not necessarily forward movement"
  (let ((next-element (svref forward element-idx))
        (prev-element (svref reverse element-idx)))
    ;; remove element from sequence
    (setf (svref reverse next-element) prev-element)
    (setf (svref forward prev-element) next-element))
  (let* ((amount (1+ (mod (1- shift) (1- (length forward)))))
         (target-index (follow-pointer forward element-idx amount)))
    (psetf (svref reverse element-idx) target-index
           (svref reverse (svref forward target-index)) element-idx
           (svref forward element-idx) (svref forward target-index)
           (svref forward target-index) element-idx))
  (values forward reverse))

(defun shuffle! (forward reverse element-idx shift)
  (cond
    ((zerop shift))
    ((plusp shift)
     (move! forward reverse element-idx shift))
    ((move! reverse forward element-idx (abs shift))))
  (values forward reverse))

(defun shuffle-pointers (msg repeat)
  (multiple-value-bind (forward reverse) (directional-pointers (length msg))
    (dotimes (_ repeat)
      (dotimes (element-idx (length msg))
        ;; (format t "st: ~a f: ~a r: ~a~%" (ordered-series msg forward) forward reverse)
        (shuffle! forward reverse element-idx (svref msg element-idx))))
    (values forward reverse)))

(defun ordered-series (msg forward)
  (let* ((len (length msg))
         (series (make-array len)))
    (do ((i (position 0 msg) (svref forward i))
         (count 0 (1+ count)))
        ((<= len count) series)
      (setf (svref series count)
            (svref msg i)))))

(defun solver (repeat message)
  (let ((new-array
          (ordered-series message (shuffle-pointers message repeat))))
    (+
     (svref new-array (mod 1000 (length new-array)))
     (svref new-array (mod 2000 (length new-array)))
     (svref new-array (mod 3000 (length new-array))))))


(defun times-decrypt-key (msg)
  (map 'vector (lambda (x) (* 811589153 x)) msg))

(fiveam:test solutions
  (fiveam:is (= 3 (solver 1 *msg*)))
  (fiveam:is (= 1623178306 (solver 10 (times-decrypt-key *msg*))))
  (let ((input-msg (map 'vector #'parse-integer (uiop:read-file-lines "input"))))
    (fiveam:is (= 7225 (solver 1 input-msg)))
    (fiveam:is (= 548634267428 (solver 10 (times-decrypt-key input-msg))))))