;;;; aoc-2022-5.lisp (defpackage #:aoc/2022/5 (:use #:cl) (:import-from #:alexandria #:appendf #:with-gensyms)) (in-package #:aoc/2022/5) (defparameter +initial-stacks+ (list '(T F V Z C W S Q) '(B R Q) '(S M P Q T Z B) '(H Q R F V D) '(P T S B D L G J) '(Z T R W) '(J R F S N M Q H) '(W H F N R) '(B R P Q T Z J))) (defvar *stacks* (copy-seq +initial-stacks+)) (defun reset () (setf *stacks* (copy-seq +initial-stacks+))) (defun move (n &key from to) (loop :for i :from 1 :to n :do (push (pop (nth (1- from) *stacks*)) (nth (1- to) *stacks*)))) (defun take (l &optional (n 1)) (declare (type list l)) (subseq l 0 n)) (defmacro takef (l &optional (n 1)) (with-gensyms (tail) `(let ((,tail (last ,l (- (length ,l) ,n)))) (prog1 (take ,l ,n) (setf ,l ,tail))))) (defmacro pushn (n from to) (with-gensyms (head) `(let ((,head (reverse (takef ,from ,n)))) (loop :for i :in ,head :do (push (pop ,head) ,to))))) (defun move1 (n &key from to) (pushn n (nth (1- from) *stacks*) (nth (1- to) *stacks*))) (defun part1 () (load "input-5A") (loop :for stack :in *stacks* :collect (first stack))) (defun part2 () (load "input-5B") (loop :for stack :in *stacks* :collect (first stack)))