aboutsummaryrefslogtreecommitdiff
path: root/2022/5.lisp
blob: 9adb5416811bdd0aaf01a3738d5c262fbe996799 (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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
;;;; 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)))