[p18] cleanup code

main
Jacopo De Simoi 10 months ago
parent cb4254e849
commit ca90ab859d
  1. 84
      p18/p18.org

@ -18,70 +18,66 @@ First parse with regex to make into a list
end-pos (list (- width 1) (- height 1)))
(setq full-data data)
#+end_src
now declare the usual helper functions
Now define the usual helper functions
#+begin_src emacs-lisp :results none
(defun neighbour (p dir)
"Returns the neighbour to P in the direction DIR"
(list (+ (car p) (car dir))
(+ (cadr p) (cadr dir))))
(defun neighbour (p dir)
"Returns the neighbour to P in the direction DIR"
(list (+ (car p) (car dir))
(+ (cadr p) (cadr dir))))
(defun within-bounds-p (p)
(let ((x (car p))
(y (cadr p)))
(and (>= x 0) (< x width)
(>= y 0) (< y height))))
(defun within-bounds-p (p)
(let ((x (car p))
(y (cadr p)))
(and (>= x 0) (< x width)
(>= y 0) (< y height))))
(defun corrupted-p (p)
(-contains-p data p))
(defun corrupted-p (p)
(-contains-p data p))
(defun visited-p (p)
(-contains-p (-map #'car distances) p))
(defun visited-p (p)
(-contains-p (-map #'car distances) p))
(defun admissible-p (p)
(and (within-bounds-p p)
(not (corrupted-p p))
(not (visited-p p))))
#+end_src
Define a generic bisect function
#+begin_src emacs-lisp :results none
(defun bisect (pred begin end)
"returns the first n between BEGIN and END such that PRED n is nil"
(if (eq (1+ begin) end) end
(let ((mid (/ (+ begin end) 2)))
(if (funcall pred mid) (bisect pred mid end)
(bisect pred begin mid)))))
#+end_src
Now solve the problem
#+begin_src emacs-lisp
(defun step (new-distances)
(let ((radius (1+ (cdar new-distances)))
(sphere (-map #'car new-distances)))
(--map (cons it radius) (-filter #'admissible-p (-distinct (-mapcat (lambda (p) (--map (neighbour p it) ' ((1 0) (0 1) (-1 0) (0 -1))))
sphere))))))
(defun step (new-distances)
(let ((radius (1+ (cdar new-distances)))
(sphere (-map #'car new-distances)))
(--map (cons it radius) (-filter #'admissible-p (-distinct (-mapcat (lambda (p) (--map (neighbour p it) ' ((1 0) (0 1) (-1 0) (0 -1))))
sphere))))))
(defun out-p (n)
(setq data (-take n full-data)
distances '(((0 0) . 0)))
(setq new distances)
(let* ((data (-take n full-data))
(distances '(((0 0) . 0)))
(new distances))
(while (setq nn (step new))
(setq distances (-concat nn distances)
new nn))
(assoc end-pos distances))
(nth (- (bisect 'out-p 1024 (length full-data)) 1) full-data)
(while (setq new (step new))
(setq distances (-concat new distances)))
(assoc end-pos distances)))
;for part 1
(out-p 1024)
;for part 2
(nth (- (bisect 'out-p 1024 (length full-data)) 1) full-data)
#+end_src
#+RESULTS:
| 10 | 38 |
#+begin_src emacs-lisp
(defun bisect (pred begin end)
(if (eq (1+ begin) end) end
(let ((mid (/ (+ begin end) 2)))
(if (funcall pred mid) (bisect pred mid end)
(bisect pred begin mid))))
)
(defun ddd (x)
(< x 138))
(bisect 'ddd 10 1000)
#+end_src
#+RESULTS:
: 138

Loading…
Cancel
Save