From 7a06cbc173ad19675d2b5b941705bf0ff35fe736 Mon Sep 17 00:00:00 2001
From: Oscar Najera <hi@oscarnajera.com>
Date: Sun, 15 Jan 2023 19:05:22 +0100
Subject: solve part2 example

Realize I can have an arbitrary cube
---
 AoC2022/22/solver.lisp | 64 +++++++++++++++++++++++++++++---------------------
 1 file changed, 37 insertions(+), 27 deletions(-)

(limited to 'AoC2022')

diff --git a/AoC2022/22/solver.lisp b/AoC2022/22/solver.lisp
index 062e441..ca4b83e 100644
--- a/AoC2022/22/solver.lisp
+++ b/AoC2022/22/solver.lisp
@@ -38,21 +38,21 @@
 (defstruct state
   x-pos y-pos direction)
 
-(defun advance (field state)
+(defun wrap-step (state field)
   (destructuring-bind (height width) (array-dimensions field)
     (with-slots (direction x-pos y-pos) state
       (destructuring-bind (new-x new-y)
           (ecase direction
-            (north (list x-pos (mod (1- y-pos) height)))
-            (south (list x-pos (mod (1+ y-pos) height)))
-            (east  (list (mod (1+ x-pos) width) y-pos))
-            (west  (list (mod (1- x-pos) width) y-pos)))
+            (^ (list x-pos (mod (1- y-pos) height)))
+            (v (list x-pos (mod (1+ y-pos) height)))
+            (> (list (mod (1+ x-pos) width) y-pos))
+            (< (list (mod (1- x-pos) width) y-pos)))
         (let ((new-state (make-state :x-pos new-x :y-pos new-y :direction direction)))
           (if (aref field new-y new-x)
               new-state
-              (advance field new-state)))))))
+              (wrap-step new-state field)))))))
 
-(defun new-direction (current-direction turn &optional (directions #(north east south west)))
+(defun new-direction (current-direction turn &optional (directions #(^ > v <)))
   (svref directions
          (mod
           (+
@@ -62,32 +62,31 @@
            (position current-direction directions))
           4)))
 
-(defun walk (field state steps)
+(defun walk (field state steps advance-fn)
   (if (zerop steps)
       state
-      (let ((new-state (advance field state)))
+      (let ((new-state (funcall advance-fn state field)))
         (with-slots (x-pos y-pos) new-state
             (ecase (aref field y-pos x-pos)
-              (free (walk field new-state (1- steps)))
+              (free (walk field new-state (1- steps) advance-fn))
               (wall state))))))
 
-
 (defun decode-state (state)
   (with-slots (x-pos y-pos direction) state
     (+ (* 1000 (1+ y-pos))
        (* 4 (1+ x-pos))
        (ecase direction
-         (east 0)
-         (south 1)
-         (west 2)
-         (north 3)))))
+         (> 0)
+         (v 1)
+         (< 2)
+         (^ 3)))))
 
-(defun solver (filename)
+(defun solver (filename advance-fn)
   (multiple-value-bind (field instructions) (create-field filename)
-    (let ((state (make-state :x-pos (get-start field) :y-pos 0 :direction 'east)))
+    (let ((state (make-state :x-pos (get-start field) :y-pos 0 :direction '>)))
       (dolist (move instructions)
         (if (numberp move)
-            (setf state (walk field state move))
+            (setf state (walk field state move advance-fn))
             (setf (state-direction state) (new-direction (state-direction state) move))))
       (decode-state state))))
 
@@ -165,7 +164,7 @@
          (< (list 5 '< (lambda (_ y) (declare (ignore _)) (list (1- fl) y))))
          (^ (list 4 '< (lambda (x _) (declare (ignore _)) (list (1- fl) (- fl x 1)))))))))
 
-(defun cube-advance (state face-length)
+(defun cube-step (state face-length)
   (destructuring-bind (face x-coord y-coord) (reduced-coords state face-length)
     (with-slots (direction) state
       (let ((new-x (+ x-coord (case direction (< -1) (> 1) (t 0))))
@@ -185,15 +184,13 @@
          (state (copy-structure orig)))
     (dolist (move '(1 left 1 left 1 left))
       (if (numberp move)
-          (setf state (cube-advance state face-length))
-          (setf (state-direction state) (new-direction (state-direction state) move #(^ > v <))))
-      ;; (print state)
-      )
+          (setf state (cube-step state face-length))
+          (setf (state-direction state) (new-direction (state-direction state) move))))
     (equalp orig state)))
 
 (fiveam:test preparation
-  (fiveam:is (eq 'south (new-direction 'east 'right)))
-  (fiveam:is (eq 'west (new-direction 'north 'left)))
+  (fiveam:is (eq 'v (new-direction '> 'right)))
+  (fiveam:is (eq '< (new-direction '^ 'left)))
   (fiveam:is (equal
               (parse-instructions "10R5L5R10L4R5L5" )
               '(10 RIGHT 5 LEFT 5 RIGHT 10 LEFT 4 RIGHT 5 LEFT 5)))
@@ -212,5 +209,18 @@
     (fiveam:is (around-corner-test (1+ i) 4))))
 
 (fiveam:test solutions
-  (fiveam:is (= 6032 (solver "eg-in")))
-  (fiveam:is (= 159034 (solver "input"))))
+  (fiveam:is (= 6032 (solver "eg-in" #'wrap-step)))
+  (fiveam:is (= 159034 (solver "input" #'wrap-step)))
+  ;part 2
+  (fiveam:is (= 5031 (solver "eg-in" (lambda (state field) (cube-step state 4))))))
+
+;; (solver "input" (lambda (state field) (cube-step state 50)))
+
+;; (multiple-value-bind (field instructions) (create-field "input")
+;;     (let ((state (place-state 1 0 0 '> 4))
+;;           (advance-fn (lambda (state) (cube-step state 4))))
+;;       (dolist (move instructions)
+;;         (if (numberp move)
+;;             (setf state (walk field state move advance-fn))
+;;             (setf (state-direction state) (new-direction (state-direction state) move))))
+;;       (decode-state state)))
-- 
cgit v1.2.3