#+title: Solution to p4 Yay, a maze. Cool. No, not cool. #+begin_src emacs-lisp :results none (with-temp-buffer (insert-file-contents "input") (advent/replace-multiple-regex-buffer '(("^\\(.*\\)$" . "\"\\1\" "))) (goto-char (point-min)) (insert "(setq data '(") (goto-char (point-max)) (insert "))") (eval-buffer)) (setq data-char (-map #'advent/split-string-into-char-list data) width (length (car data-char)) height (length data-char)) #+end_src This is for part 1; easy #+begin_src emacs-lisp (defun position-valid-p (pos) (and (and (>= (car pos) 0) (< (car pos) width)) (and (>= (cadr pos) 0) (< (cadr pos) height)))) (defun roll-at-p (pos data-char) (when (position-valid-p pos) (eq ?@ (advent/char-at pos data-char)))) (setq adjacent '((-1 -1) (-1 0) (-1 1) (0 1) (0 -1) (1 -1) (1 0) (1 1))) (defun rolls-adjacent (pos data-char) (length (-non-nil (--map (roll-at-p it data-char) (--map (advent/neighbour pos it) adjacent))))) (length (--filter (< it 4) (--map (rolls-adjacent it data-char) (advent/coordinates-of ?@ data-char)))) #+end_src #+RESULTS: : 1464 Now for part two, we create a new data-char at each removal step and count how many rolls have been removed #+begin_src emacs-lisp (setq initial-roll-number (length (advent/coordinates-of ?@ data-char)) current-roll-number (1+ initial-roll-number)) (while (> current-roll-number (setq current-roll-number (length (advent/coordinates-of ?@ data-char)))) (setq data-char (--2map-indexed (if (and (= ?@ it) (<= 4 (rolls-adjacent it-multi-index data-char))) ?@ ?.) data-char))) (- initial-roll-number current-roll-number) #+end_src #+RESULTS: : 8409 #+begin_src emacs-lisp (defun -2map (fun li) (--map (-map fun it) li)) (defmacro --2map (form list) `(-2map (lambda (it) ,form) ,list)) (defun -2map-indexed (fun li) (-map-indexed (lambda (i row) (-map-indexed (lambda (j it) (funcall fun i j it)) row)) li)) (defmacro --2map-indexed (form li) `(-2map-indexed (lambda (it-index-1 it-index-2 it) ,form) ,li)) #+end_src