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

  • ystael@beehaw.org
    link
    fedilink
    arrow-up
    3
    ·
    edit-2
    4 days 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))))