adventofcode2022

My solutions for Advent of Code 2022
Log | Files | Refs

day20.lisp (2052B)


      1 (defpackage #:adventofcode2022/day20
      2   (:use #:cl #:adventofcode2022))
      3 (in-package #:adventofcode2022/day20)
      4 
      5 (defun mix (sequence)
      6   (loop with length = (1- (length sequence))
      7         for i from 0 to length
      8         for index = (position-if (lambda (item)
      9                                    (= (cadr item) i))
     10                                  sequence)
     11         for item-to-mix = (aref sequence index)
     12         for number-to-mix = (car item-to-mix)
     13         for new-index = (mod (+ index number-to-mix) length)
     14         do (cond
     15              ((> new-index index)
     16               (let ((after (subseq sequence (1+ index) (1+ new-index))))
     17                 (replace sequence after :start1 index)))
     18              ((< new-index index)
     19               (let ((before (subseq sequence new-index index)))
     20                 (replace sequence before :start1 (1+ new-index)))))
     21         do (setf (aref sequence new-index) item-to-mix)))
     22 
     23 (defun convert-sequence (inputs &key map-number)
     24   (coerce (loop for number in inputs
     25                 for i from 0
     26                 collect (list (if map-number
     27                                   (funcall map-number number)
     28                                   number)
     29                               i))
     30           'vector))
     31 
     32 (defun find-coordinates (sequence)
     33   (let ((length (length sequence))
     34         (zero (position-if (lambda (item)
     35                              (zerop (car item)))
     36                            sequence)))
     37     (+ (car (aref sequence (mod (+ zero 1000) length)))
     38        (car (aref sequence (mod (+ zero 2000) length)))
     39        (car (aref sequence (mod (+ zero 3000) length))))))
     40 
     41 (defun task1 (inputs)
     42   (let ((sequence (convert-sequence inputs)))
     43     (mix sequence)
     44     (find-coordinates sequence)))
     45 
     46 (defun task2 (inputs)
     47   (let ((sequence (convert-sequence inputs :map-number (lambda (number)
     48                                                          (* number 811589153)))))
     49     (loop repeat 10 do (mix sequence))
     50     (find-coordinates sequence)))
     51 
     52 (define-day 20
     53     (:translate-input #'parse-integer)
     54   #'task1
     55   #'task2)