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
(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