adventofcode2022

My solutions for Advent of Code 2022
Log | Files | Refs

day05.lisp (2503B)


      1 (defpackage #:adventofcode2022/day05
      2   (:use #:cl #:adventofcode2022))
      3 (in-package #:adventofcode2022/day05)
      4 
      5 (defun parse-stack (stack-lines)
      6   (let* ((indices (mapcar (lambda (x)
      7                             (parse-integer x))
      8                           (str:split " " (pop stack-lines) :omit-nulls t)))
      9          (length (apply #'max indices))
     10          (stacks (make-array length :initial-element nil)))
     11     (loop for line in stack-lines
     12           do (loop for i from 0 below length
     13                    for crate-index = (1+ (* i 4))
     14                    for crate-id = (aref line crate-index)
     15                    when (not (char= #\Space crate-id))
     16                      do (push crate-id
     17                               (aref stacks i))))
     18     stacks))
     19 
     20 (defun parse-input (inputs)
     21   (loop with stack-lines = nil
     22         with rules = nil
     23         with rules-p = nil
     24         for input in inputs
     25         if (= 0 (length input))
     26           do (setf rules-p t)
     27         else if rules-p
     28                do (let ((parts (str:split " " input)))
     29                     (push (list (parse-integer (second parts))
     30                                 (parse-integer (fourth parts))
     31                                 (parse-integer (sixth parts)))
     32                           rules))
     33         else
     34           do (push input stack-lines)
     35         finally (return (values (parse-stack stack-lines)
     36                                 (reverse rules)))))
     37 
     38 (defun task1 (inputs)
     39   (multiple-value-bind (stacks rules)
     40       (parse-input inputs)
     41     (loop for rule in rules
     42           do (loop for i from 1 to (car rule)
     43                    for from = (1- (cadr rule))
     44                    for to = (1- (caddr rule))
     45                    for crate = (pop (aref stacks from))
     46                    do (push crate (aref stacks to))))
     47     (coerce (loop for i from 0 below (length stacks)
     48                   collect (first (aref stacks i)))
     49             'string)))
     50 
     51 (defmacro popn (place n)
     52   `(loop for i from 0 below ,n
     53          collect (pop ,place)))
     54 
     55 (defun task2 (inputs)
     56   (multiple-value-bind (stacks rules)
     57       (parse-input inputs)
     58     (loop for rule in rules
     59           for from = (1- (cadr rule))
     60           for to = (1- (caddr rule))
     61           for crates = (popn (aref stacks from) (car rule))
     62           do (setf (aref stacks to)
     63                    (nconc crates (aref stacks to))))
     64     (coerce (loop for i from 0 below (length stacks)
     65                   collect (first (aref stacks i)))
     66             'string)))
     67 
     68 (define-day 5
     69     ()
     70   #'task1
     71   #'task2)