;; this one abuses the file format and white space (ql:quickload :fiveam) (defun build-stacks (in) (let* ((input (read-line in)) (stack-amount (ceiling (/ (length input) 4))) (stacks (make-array stack-amount :initial-element nil))) (loop for dock = input then (read-line in) while (not (eq (aref dock 1) #\1)) do (loop for idx from 0 below stack-amount for entry = (aref dock (+ 1 (* 4 idx))) unless (eq entry #\ ) do (push entry (aref stacks idx)))) (map 'vector #'nreverse stacks))) (defun single-move! (stacks amount from to) (dotimes (_ amount) (push (pop (aref stacks from)) (aref stacks to)))) (defun bulk-move! (stacks amount from to) (setf (aref stacks to) (append (subseq (aref stacks from) 0 amount) (aref stacks to))) (setf (aref stacks from) (subseq (aref stacks from) amount))) (defun apply-moves (execution in stacks) (loop for action = (read in nil nil) while action do (let ((amount (read in nil nil)) (from (progn (read in nil nil) (1- (read in nil nil)))) (to (progn (read in nil nil) (1- (read in nil nil))))) (funcall execution stacks amount from to))) stacks) (defun solver (execution) (with-open-file (in "input") (map 'string #'car (apply-moves execution in (build-stacks in))))) (fiveam:test results (fiveam:is (equal "TPGVQPFDH" (solver #'single-move!))) (fiveam:is (equal "DMRDFRHHH" (solver #'bulk-move!))))