Skip to content

Files

Latest commit

1959899 · Dec 16, 2023

History

History
155 lines (152 loc) · 5.23 KB

2022.20.org

File metadata and controls

155 lines (152 loc) · 5.23 KB

Day 20

Executing this code

If you have a lisp installation, emacs, org-mode, and org-babel support for lisp installed you can run this by:

  1. Starting slime (M-x slime)
  2. Typing C-c C-c in the block initialize.
  3. In the repl type (in-package :aoc-2022-20)
  4. Typing C-c C-c in the block answers

Initial stuffs

Packages to load

(unless (find-package :priority-queue)
  (ql:quickload "priority-queue"))
(unless (find-package :cl-ppcre)
  (ql:quickload "cl-ppcre"))
(unless (find-package :parseq)
  (ql:quickload "parseq"))
(unless (find-package :lparallel)
  (ql:quickload "lparallel"))
(unless (find-package :fiveam)
  (ql:quickload "fiveam"))
(unless (find-package :series)
  (ql:quickload "series"))
(unless (find-package :cl-permutation)
  (ql:quickload "cl-permutation"))
(unless (find-package :bordeaux-threads)
  (ql:quickload "bordeaux-threads"))

Create package for this day

<<packages>>
(defpackage :aoc-2022-20
  (:use :common-lisp
        :parseq
        :fiveam)
  (:export :problem-a
           :problem-b))
(in-package :aoc-2022-20)

Input

(defun process-stream (in)
  (loop for line = (read-line in nil)
        while line
        collect (parse-integer line)))
(defun read-input (file)
  (with-open-file (in file)
    (process-stream in)))
(defparameter *input*
  (read-input "input/20.txt"))

Part 1

(defun mix (numbers)
  (let ((table (make-array (length numbers) :initial-contents numbers))
        (sequence (loop for i from 0 below (length numbers) collect i)))
    (setf (cdr (last sequence)) sequence)
    (loop for i from 0 below (length table)
          for previous = (loop for pos on sequence
                               until (= (cadr pos) i)
                               finally (return pos))
          for element = (cdr previous)
          for value = (aref table (car element))
          for shift-by = (mod value (1- (length table)))
          for new-previous = (nthcdr shift-by element)
          unless (zerop (mod value (1- (length table))))
            do (setf (cdr previous) (cdr element)) ;; remove the number
               (psetf (cdr new-previous) element
                      (cdr element) (cdr new-previous)))
    (let* ((zero (position 0 table))
           (start (loop for pos on sequence
                        until (= (car pos) zero)
                        finally (return pos))))
      (+ (aref table (elt start 1000))
         (aref table (elt start 2000))
         (aref table (elt start 3000))))))

(defun problem-a () (format t "Problem 20 A: ~a~%" (mix *input*)))

Part 2

(defun mix-decrypt (numbers &key (decryption-key 811589153) (cycles 10))
  (let ((table (make-array (length numbers) :initial-contents numbers))
        (sequence (loop for i from 0 below (length numbers) collect i)))
    (loop for i from 0 below (length table)
          for n across table
          do (setf (aref table i) (* decryption-key n)))
    (setf (cdr (last sequence)) sequence)
    (loop repeat cycles
          do (loop for i from 0 below (length table)
                   for previous = (loop for pos on sequence
                                        until (= (cadr pos) i)
                                        finally (return pos))
                   for element = (cdr previous)
                   for value = (aref table (car element))
                   for shift-by = (mod value (1- (length table)))
                   for new-previous = (nthcdr shift-by element)
                   unless (zerop shift-by)
                     do (shiftf (cdr previous) (cdr element)
                                (cdr new-previous) element)))
    (let* ((zero (position 0 table))
           (start (loop for pos on sequence
                        until (= (car pos) zero)
                        finally (return pos))))
      (+ (aref table (elt start 1000))
         (aref table (elt start 2000))
         (aref table (elt start 3000))))))
(defun problem-b () (format t "Problem 20 B: ~a~%" (mix-decrypt *input*)))

Putting it all together

<<read-input>>
<<input>>
<<initialize>>
<<structs>>
<<functions>>
<<input>>
<<problem-a>>
<<problem-b>>
(problem-a)
(problem-b)

Answer

Problem 20 A: 19559
Problem 20 B: 912226207972

Test Cases

(def-suite aoc.2022.20)
(in-suite aoc.2022.20)

(run! 'aoc.2022.20)

Test Results

Thoughts