|
|
|
|
@ -1,9 +1,10 @@ |
|
|
|
|
#+title: Solution to p15 |
|
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
Process the input file to create the maps and the sequence of moves |
|
|
|
|
#+begin_src emacs-lisp :results none |
|
|
|
|
(require 'dash) |
|
|
|
|
(with-temp-buffer |
|
|
|
|
(insert-file-contents "input-fuffa") |
|
|
|
|
(insert-file-contents "input") |
|
|
|
|
(goto-char (point-min)) |
|
|
|
|
(replace-regexp "^\\(#.*#\\)$" "\"\\1\"") |
|
|
|
|
(goto-char (point-min)) |
|
|
|
|
@ -13,7 +14,7 @@ |
|
|
|
|
(goto-char (point-min)) |
|
|
|
|
(replace-regexp "<" "( -1 0)") |
|
|
|
|
(goto-char (point-min)) |
|
|
|
|
(replace-regexp ">" "( 1 0)") |
|
|
|
|
(replace-regexp ">" "( 1 0)") |
|
|
|
|
(goto-char (point-min)) |
|
|
|
|
(replace-regexp "v" "( 0 1)") |
|
|
|
|
(goto-char (point-min)) |
|
|
|
|
@ -21,106 +22,93 @@ |
|
|
|
|
(goto-char (point-max)) |
|
|
|
|
(insert "))") |
|
|
|
|
(eval-buffer)) |
|
|
|
|
|
|
|
|
|
#+end_src |
|
|
|
|
|
|
|
|
|
#+RESULTS: |
|
|
|
|
read and parse the map |
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
(setq map-things (-map (lambda (str) (-map #'string-to-char (split-string str "\\|.+" t))) |
|
|
|
|
map) |
|
|
|
|
height (length map-things) |
|
|
|
|
width (length (car map-things))) |
|
|
|
|
|
|
|
|
|
(defun stuff-coordinates (e) |
|
|
|
|
Read and parse the map to extract the positions of the various |
|
|
|
|
elements |
|
|
|
|
#+begin_src emacs-lisp :results none |
|
|
|
|
(setq map-things (-map |
|
|
|
|
(lambda (str) (-map #'string-to-char (split-string |
|
|
|
|
str "\\|.+" t))) |
|
|
|
|
map) |
|
|
|
|
height (length map-things) |
|
|
|
|
width (length (car map-things))) |
|
|
|
|
|
|
|
|
|
(defun coordinates-of (e) |
|
|
|
|
(-map #'cadr |
|
|
|
|
(--filter (eq (car it) e) |
|
|
|
|
(-mapcat #'identity |
|
|
|
|
(-map-indexed (lambda (y l) (-map-indexed (lambda (x el) (list el (list x y))) l)) map-things)))) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
(setq walls (stuff-coordinates ?#) |
|
|
|
|
crates (stuff-coordinates ?O) |
|
|
|
|
robot (car (stuff-coordinates ?@))) |
|
|
|
|
(--filter (eq (car it) e) |
|
|
|
|
(-mapcat #'identity |
|
|
|
|
(-map-indexed (lambda (y l) |
|
|
|
|
(-map-indexed (lambda (x el) (list el (list x y))) l)) |
|
|
|
|
map-things))))) |
|
|
|
|
|
|
|
|
|
(setq walls (coordinates-of ?#) |
|
|
|
|
crates (coordinates-of ?O) |
|
|
|
|
robot (car (coordinates-of ?@))) |
|
|
|
|
#+end_src |
|
|
|
|
|
|
|
|
|
#+RESULTS: |
|
|
|
|
| 2 | 2 | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
(defun thing-at (p) |
|
|
|
|
(cond |
|
|
|
|
((equal p robot) 'robot) |
|
|
|
|
((-contains-p walls p) 'wall) |
|
|
|
|
((-contains-p crates p) 'crate) |
|
|
|
|
(t nil))) |
|
|
|
|
|
|
|
|
|
(defun neigh (p dir) |
|
|
|
|
(list (+ (car p) (car dir)) (+ (cadr p) (cadr dir)))) |
|
|
|
|
|
|
|
|
|
(defun do-move (what from to) |
|
|
|
|
Implement the move logic. The key function is try-move: it tries to |
|
|
|
|
move stuff in some direction and push anything it can along the way by |
|
|
|
|
calling itself recursively to see if whatever is on the way can itself |
|
|
|
|
be pushed. |
|
|
|
|
#+begin_src emacs-lisp :results none |
|
|
|
|
(defun thing-at (p) |
|
|
|
|
"Returns which object (if any) is present at position P" |
|
|
|
|
(cond |
|
|
|
|
((equal p robot) 'robot) |
|
|
|
|
((-contains-p walls p) 'wall) |
|
|
|
|
((-contains-p crates p) 'crate) |
|
|
|
|
(t nil))) |
|
|
|
|
|
|
|
|
|
(defun neighbour (p dir) |
|
|
|
|
"Returns the neighbour to P in the direction DIR" |
|
|
|
|
(list (+ (car p) (car dir)) |
|
|
|
|
(+ (cadr p) (cadr dir)))) |
|
|
|
|
|
|
|
|
|
(defun do-move (from to) |
|
|
|
|
"Updates the content of the warehouse by moving whatever is at |
|
|
|
|
FROM to the position TO" |
|
|
|
|
(cond |
|
|
|
|
((eq (thing-at from) 'crate) (setq crates (-replace from to crates))) |
|
|
|
|
(t (setq robot to)))) |
|
|
|
|
|
|
|
|
|
(defun try-move (p dir) |
|
|
|
|
"Try to move the object at P in the direction DIR" |
|
|
|
|
(let ((thing (thing-at p))) |
|
|
|
|
(cond |
|
|
|
|
((equal what 'crate) (setq crates (-replace from to crates))) |
|
|
|
|
(t (setq robot to)) |
|
|
|
|
(print crates)) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
(defun move (p dir) |
|
|
|
|
(let ((thing (thing-at p))) |
|
|
|
|
(cond |
|
|
|
|
((not thing) t) |
|
|
|
|
((equal thing 'wall)) |
|
|
|
|
(t (let ((dest (neigh p dir))) |
|
|
|
|
(when (move dest dir) |
|
|
|
|
(do-move thing p dest))))))) |
|
|
|
|
((not thing) t) |
|
|
|
|
((eq thing 'wall) nil) |
|
|
|
|
(t (let ((dest (neighbour p dir))) |
|
|
|
|
(when (try-move dest dir) |
|
|
|
|
(do-move p dest))))))) |
|
|
|
|
#+end_src |
|
|
|
|
|
|
|
|
|
#+RESULTS: |
|
|
|
|
: move |
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
This is just to make pretty pictures of the current state |
|
|
|
|
#+begin_src emacs-lisp :results none |
|
|
|
|
(defun make-bg () |
|
|
|
|
(insert (apply #'concat (-repeat height (concat (concat (-repeat width ?. )) "\n"))))) |
|
|
|
|
|
|
|
|
|
(defun plot (p s) |
|
|
|
|
(goto-line (- (cadr p) 1)) |
|
|
|
|
(move-to-column (car p)) |
|
|
|
|
(insert s) |
|
|
|
|
(delete-char 1)) |
|
|
|
|
|
|
|
|
|
(defun plot-walls () |
|
|
|
|
(--map (plot it "#") walls)) |
|
|
|
|
|
|
|
|
|
(defun plot-crates () |
|
|
|
|
(--map (plot it "O") crates)) |
|
|
|
|
(defun plot (p s) |
|
|
|
|
(goto-line (+ (cadr p) 1)) |
|
|
|
|
(move-to-column (car p)) |
|
|
|
|
(insert s) |
|
|
|
|
(delete-char 1)) |
|
|
|
|
|
|
|
|
|
(defun save-pic () |
|
|
|
|
(with-temp-buffer |
|
|
|
|
(make-bg) |
|
|
|
|
(plot-walls) |
|
|
|
|
(plot-crates) |
|
|
|
|
(--map (plot it "#") walls); should use --each |
|
|
|
|
(--map (plot it "O") crates) |
|
|
|
|
(plot robot "@") |
|
|
|
|
(write-file "test-out"))) |
|
|
|
|
|
|
|
|
|
#+end_src |
|
|
|
|
|
|
|
|
|
#+RESULTS: |
|
|
|
|
: save-pic |
|
|
|
|
|
|
|
|
|
Finally, implement the moves and compute the result for part 1 |
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
(move robot (car commands)) |
|
|
|
|
(setq commands (cdr commands)) |
|
|
|
|
(--map (try-move robot it) commands) |
|
|
|
|
(save-pic) |
|
|
|
|
(-reduce #'+ (--map (+ (car it) (* 100 (cadr it))) crates)) |
|
|
|
|
#+end_src |
|
|
|
|
|
|
|
|
|
#+RESULTS: |
|
|
|
|
|
|
|
|
|
#+begin_src |
|
|
|
|
(--map (move robot it) commands) |
|
|
|
|
|
|
|
|
|
; (-reduce #'+ (--map (+ (car it) (* 100 (cadr it))) crates)) |
|
|
|
|
|
|
|
|
|
#+end_src |
|
|
|
|
#+RESULTS: |
|
|
|
|
: 2024 |
|
|
|
|
crates |
|
|
|
|
: 1371036 |
|
|
|
|
|