aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/05/solver.lisp
blob: 809439b2e53b000ec96066b2de54c2ee3e85f91b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
;; 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!))))