You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3.0 KiB
3.0 KiB
Solution to p20
Load map
(require 'dash)
(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-chars (-map #'advent/split-string-into-char-list data)
height (length data-chars)
width (length (car data-chars)))
(defun char-at (p)
(nth (car p) (nth (cadr p) data-chars)))
(setq char-things-alist '((?# . wall)
(?. . free)
(?S . start)
(?E . end)))
(defun thing-at (p)
"Returns which object (if any) is present at position P"
(cdr (assoc (char-at p) char-things-alist)))
(defun starting-pos ()
(car (advent/coordinates-of ?S data-chars)))
Let the stack burn
(setq max-lisp-eval-depth 1000000) ; burn baby burn
First, we explore the maze and record the path from START to END
(defun explore (p dir &optional past)
"Explore the maze starting at position P and in the direction
DIR. Returns a list of positions traversed END to START"
(if (eq (thing-at p) 'end) (cons p past)
(let* ((forward-dirs (--filter (>= (advent/dot it dir) 0)
'((0 1) (0 -1) (-1 0) (1 0))))
(new-dir (car (--filter (not (eq (thing-at (advent/neighbour p it)) 'wall)) forward-dirs))))
(explore (advent/neighbour p new-dir) new-dir (cons p past)))))
(setq distance-alist (-map-indexed (lambda (x y) (cons y x))
(explore (starting-pos) '(0 0))))
Now look for gaps:
(defun subtract-nil (a b)
(when a (- a b)))
(length
(--filter (>= it 100)
(--map (- it 2)
(-flatten (-non-nil (--map (-non-nil
(-map (lambda (dir) (subtract-nil (cdr (assoc (advent/neighbour (car it) dir) distance-alist)) (cdr it)))
'((0 2) (0 -2) (2 0) (-2 0))))
distance-alist))))))
1426
Alternatively, collect all element of the path that are –in the taxicab distance– closer than 20 to any given element of the path, then compute the time saved by using the cheat and filter only those that save at least 100 picoseconds
(length
(--filter (>= it 100)
(-flatten
(-map (lambda (x) (--map (- (cdar it) (cdr x) (cdr it))
(--filter (<= (cdr it) 20)
(--map (cons it (advent/taxicab-distance (car it) (car x))) distance-alist))))
distance-alist))))
1000697