Day 6: Trash Compactor

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 2 points 9 months ago*

Ironically for Lisp, a good chunk of the work here is type conversion, because strings, vectors, multidimensional arrays, characters, and numbers don't have implicit conversions between them; you have to specify what you want explicitly. I also found it easier to manually transpose the character array for part 2 rather than traverse in column-major order, because that makes the relationship between input and output data structure more transparent.

(ql:quickload :str)
(ql:quickload :array-operations)

(defun parse-line-1 (line)
  (let ((broken-line (str:split " " (str:collapse-whitespaces (str:trim line)))))
    (mapcar #'(lambda (s)
                (cond ((equal s "+") #'+)
                      ((equal s "*") #'*)
                      (t (parse-integer s))))
            broken-line)))

(defun read-inputs-1 (filename)
  (let* ((input-lines (uiop:read-file-lines filename)))
    (mapcar #'parse-line-1 input-lines)))

(defun main-1 (filename)
  (let* ((problems (read-inputs-1 filename))
         (arguments (apply #'mapcar #'list (butlast problems))))
    (reduce #'+ (mapcar #'apply (car (last problems)) arguments))))

(defun parse-operands-2 (lines)
  (let* ((initial-rows (length lines))
         (initial-cols (length (car lines)))
         (flat-chars (make-array (list (* initial-rows initial-cols))
                                 :initial-contents (apply #'concatenate 'string lines)))
         (box-chars (make-array (list initial-rows initial-cols) :displaced-to flat-chars))
         (transposed-chars (aops:each-index (i j) (aref box-chars j i))))
    (loop for cv across (aops:split transposed-chars 1)
          for s = (str:trim (coerce cv 'string))
          collect (if (zerop (length s)) nil (parse-integer s)))))

(defun list-split (xs sep &optional (predicate #'equal))
  (let ((current nil)
        (result nil))
    (loop for x in xs
          do (if (funcall predicate x sep)
                 (progn
                   (setf result (cons (reverse current) result))
                   (setf current nil))
                 (setf current (cons x current)))
          finally (setf result (cons (reverse current) result)))
    (reverse result)))

(defun main-2 (filename)
  (let* ((lines (uiop:read-file-lines filename))
         (operators (parse-line-1 (car (last lines))))
         (operands (parse-operands-2 (butlast lines))))
    (loop for rator in operators
          for rands in (list-split operands nil)
          sum (apply rator rands))))
  • source