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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 3 points 10 months 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))
  • source