New attempt

main
Jacopo De Simoi 11 months ago
parent ba77e72761
commit 9978ef9367
  1. 65
      p16/p16.org

@ -4,7 +4,7 @@ Load map
#+begin_src emacs-lisp :results none
(require 'dash)
(with-temp-buffer
(insert-file-contents "input-test2")
(insert-file-contents "input")
(goto-char (point-min))
(replace-regexp "^\\(#.*#\\)$" "\"\\1\"")
(goto-char (point-min))
@ -75,45 +75,72 @@ associated scores;
(explore start '(1 0) 0)
#+end_src
For debugging, print the map
#+begin_src emacs-lisp
(defun plot (p s)
(goto-line (+ (cadr p) 1))
(move-to-column (car p))
(insert s)
(delete-char 1))
(defun print-map (p)
(with-temp-buffer
(-each data (lambda (x) (insert x) (insert "\n")))
(-each book (lambda (x) (if (cdr x) (plot (caar x) ?x)
(plot (caar x) ?!))))
(plot p ?@)
(write-file "tmp")) )
#+end_src
#+RESULTS:
: print-map
In principle the above would work as-is, but it is not very efficient.
In the version below, we record dead-ends and partial solutions
#+begin_src emacs-lisp
(defun >nil (a b)
(when b
(or (not a) (> a b))))
(when (numberp b)
(or (not (numberp a)) (> a b))))
(defun subtract-nil (a b)
(when (and a b)
(when (and (numberp a) (numberp b))
(- a b)))
(defun +nil (a b)
(when (and a b)
(when (and (numberp a) (numberp b))
(+ a b)))
(defun neighbour-maybe (p dir newdir)
(if (not (equal dir newdir)) p
(neighbour p newdir)))
(defun explore (p dir score &optional past)
(defun forward-dirs (dir olddir)
(if (not (equal dir olddir)) (list dir)
(cons dir (--filter (= (dot it dir) 0) '((0 1) (0 -1) (-1 0) (1 0))))))
(defun explore (p dir old-dir score &optional past)
"Explore the maze starting at position P and in the direction
DIR. Returns nil if we will dead-end or loop or the score
if we reach the end"
(if (eq (thing-at p) 'end) score
(if (assoc (list p dir) book) (+nil score (cdr (assoc (list p dir) book))) ; check the book for this position and direction
(unless (-contains-p (cdr past) p) ; loop
(let* ((forward-dirs (--filter (>= (dot it dir) 0) '((0 1) (0 -1) (-1 0) (1 0))))
(acceptable-dirs (--filter (not (eq (thing-at (neighbour p it)) 'wall)) forward-dirs))
(new-score (-min-by #'>nil (-map (lambda (newdir)
(explore (neighbour-maybe p dir newdir) newdir
(+ score (if (equal newdir dir) 1 1000))
(cons p past)))
acceptable-dirs))))
(push (cons (list p dir) (subtract-nil new-score score)) book)
new-score)))))
(setq book nil)
(explore start '(1 0) 0)
(if (-contains-p (cdr past) p) 'loop
(let* ((acceptable-dirs (--filter (not (eq (thing-at (neighbour p it)) 'wall)) (forward-dirs dir old-dir)))
(new-score (-min-by #'>nil (-map (lambda (newdir)
(explore (neighbour-maybe p dir newdir) newdir dir
(+ score (if (equal newdir dir) 1 1000))
(-distinct (cons p past))))
acceptable-dirs))))
(when (not (eq new-score 'loop)) (push (cons (list p dir) (subtract-nil new-score score)) book))
new-score)))))
(setq book nil)
(explore start '(1 0) '(1 0) 0)
#+end_src
#+RESULTS:
: 11048
(print-map)

Loading…
Cancel
Save