From c7204bf0b489b4c45af7aef3307c93e51b3f6eb7 Mon Sep 17 00:00:00 2001 From: Jacopo De Simoi Date: Tue, 15 Apr 2025 12:33:34 -0400 Subject: [PATCH] Solution to p15 part 1 --- p15/p15.org | 152 ++++++++++++++++++++++++---------------------------- 1 file changed, 70 insertions(+), 82 deletions(-) diff --git a/p15/p15.org b/p15/p15.org index 95882cd..dcb25df 100644 --- a/p15/p15.org +++ b/p15/p15.org @@ -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