Day 4: Printing Department

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
    ·
    1 day ago

    This is the first day I’ve wished I were working in J, like last year, instead of Lisp. Common Lisp arrays show the age of the language design. They’re basically C arrays with less convenient syntax; if you want higher-order array iteration you have to write it yourself or use a package that provides it. This solution is also less efficient than it could be for part 2, because I recompute the full neighbors array on each iteration rather than updating it incrementally.

    (defun read-inputs (filename)
      (let* ((input-lines (uiop:read-file-lines filename))
             (rows (length input-lines))
             (cols (length (car input-lines)))
             (result (make-array (list rows cols) :initial-element 0)))
        (loop for line in input-lines
              for y from 0 to (1- rows)
              do (loop for x from 0 to (1- cols)
                       if (eql (char line x) #\@)
                         do (setf (aref result y x) 1)))
        result))
    
    (defun neighbors (grid)
      (let* ((dimensions (array-dimensions grid))
             (rows (car dimensions))
             (cols (cadr dimensions))
             (result (make-array dimensions :initial-element 0)))
        (flet ((neighbors-at (y x)
                 (loop for dy from -1 to 1
                       sum (loop for dx from -1 to 1
                                 sum (let ((yy (+ y dy))
                                           (xx (+ x dx)))
                                       (if (and (>= yy 0)
                                                (< yy rows)
                                                (>= xx 0)
                                                (< xx cols)
                                                (not (and (= dx 0) (= dy 0)))
                                                (> (aref grid yy xx) 0))
                                           1
                                           0))))))
          (loop for y from 0 to (1- rows)
                do (loop for x from 0 to (1- cols)
                         do (setf (aref result y x) (neighbors-at y x))))
          result)))
    
    (defun main-1 (filename)
      (let* ((grid (read-inputs filename))
             (dimensions (array-dimensions grid))
             (neighbors-grid (neighbors grid)))
        (loop for y from 0 to (1- (car dimensions))
              sum (loop for x from 0 to (1- (cadr dimensions))
                        sum (if (and (> (aref grid y x) 0)
                                     (< (aref neighbors-grid y x) 4))
                                1
                                0)))))
    
    (defun remove-accessible (grid)
      (let* ((dimensions (array-dimensions grid))
             (neighbors-grid (neighbors grid))
             (removed 0))
        (loop for y from 0 to (1- (car dimensions))
              do (loop for x from 0 to (1- (cadr dimensions))
                       do (if (and (> (aref grid y x) 0)
                                   (< (aref neighbors-grid y x) 4))
                              (progn
                                (setf (aref grid y x) 0)
                                (incf removed)))))
        removed))
    
    (defun main-2 (filename)
      (let ((grid (read-inputs filename))
            (removed 0))
        (loop for this-removed = (remove-accessible grid)
              until (zerop this-removed)
              do (incf removed this-removed))
        removed))