aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOscar Najera <hi@oscarnajera.com>2022-12-09 13:58:19 +0100
committerOscar Najera <hi@oscarnajera.com>2022-12-09 13:58:19 +0100
commit7e207bf01575550fcae82103d1e6573d7b7b5216 (patch)
tree843666467a675c667248eca6c05c2cacda77d5be
parent35127773880a4cf985779e6b82e04209dcf2792c (diff)
downloadscratch-7e207bf01575550fcae82103d1e6573d7b7b5216.tar.gz
scratch-7e207bf01575550fcae82103d1e6573d7b7b5216.tar.bz2
scratch-7e207bf01575550fcae82103d1e6573d7b7b5216.zip
[AoC2022] Elips 09-02
-rw-r--r--AoC2022/09/solver.el70
1 files changed, 44 insertions, 26 deletions
diff --git a/AoC2022/09/solver.el b/AoC2022/09/solver.el
index d1eac37..cf5ac7f 100644
--- a/AoC2022/09/solver.el
+++ b/AoC2022/09/solver.el
@@ -25,14 +25,13 @@
(defsubst solver-diagonal (vec)
(and (= 1 (abs (car vec))) (= 1 (abs (cdr vec)))))
-
(defun solver-move (direction)
(cl-ecase direction
('R (lambda (x) (cl-incf (car x))))
('L (lambda (x) (cl-decf (car x))))
('U (lambda (x) (cl-incf (cdr x))))
('D (lambda (x) (cl-decf (cdr x))))))
-;; WARN This need to be bytecompiled otherwise the lambda is not capturing diff-v in the closure
+
(defun solver-puller (diff-v)
(let ((distance (solver-distance-1 diff-v)))
(cond
@@ -42,37 +41,56 @@
(pcase diff-v
(`(0 . ,d) (solver-move (if (= d 2) 'U 'D)))
(`(,d . 0) (solver-move (if (= d 2) 'R 'L)))))
- ((= distance 3)
+ ((<= 3 distance 4)
(lambda (x)
(funcall (solver-move (if (< 0 (car diff-v)) 'R 'L)) x)
(funcall (solver-move (if (< 0 (cdr diff-v)) 'U 'D)) x)))
- (t (error "Head moved too far")))))
+ (t (error "Leader moved too far")))))
-(with-temp-buffer
- (insert-file-contents "input")
-;; (insert "R 4
-;; U 4
-;; L 3
-;; D 1
-;; R 4
-;; D 1
-;; L 5
-;; R 2")
+(defun solver-input (data-string)
+ (thread-last
+ (split-string data-string "\n" t)
+ (mapcar (lambda (inst) (let ((move (split-string inst)))
+ (cons (intern (car move))
+ (string-to-number (cadr move))))))))
+
+(defun solver (moves rope)
(let (path
- (head (cons 0 0))
- (tail (cons 0 0))
- (moves
- (thread-last
- (split-string (buffer-string) "\n" t)
- (mapcar (lambda (inst) (let ((move (split-string inst)))
- (cons (intern (car move))
- (string-to-number (cadr move))))))
- )))
+ (head (car rope))
+ (end (car (last rope))))
(dolist (move moves)
(dotimes (_ (cdr move))
(funcall (solver-move (car move)) head)
- (funcall (solver-puller (solver-diff head tail)) tail)
- (push (cons (car tail) (cdr tail)) path)))
- (= 6384 (length (cl-remove-duplicates path :test #'equal))))
+ (cl-loop for (leader follower) on rope while follower
+ do (funcall (solver-puller (solver-diff leader follower)) follower))
+ ;; (message "%S" rope)
+ (push (cons (car end) (cdr end)) path)))
+ (cl-remove-duplicates path :test #'equal)))
+
+(defconst solver-eg-1 (solver-input "R 4
+ U 4
+ L 3
+ D 1
+ R 4
+ D 1
+ L 5
+ R 2"))
+(defconst solver-eg-2 (solver-input "R 5
+U 8
+L 8
+D 3
+R 17
+D 10
+L 25
+U 20"))
+(defconst solver-problem (solver-input (with-temp-buffer (insert-file-contents "input") (buffer-string))))
+(ert-deftest test-solver ()
+ ;; part 1
+ (should (= 13 (length (solver solver-eg-1 (list (cons 0 0) (cons 0 0))))))
+ (should (= 6384 (length (solver solver-problem (list (cons 0 0) (cons 0 0))))))
+ ;; part 2
+ (should (= 1 (length (solver solver-eg-1 (cl-loop repeat 10 collect (cons 0 0))))))
+ (should (= 36 (length (solver solver-eg-2 (cl-loop repeat 10 collect (cons 0 0))))))
+ (should (= 2734 (length (solver solver-problem (cl-loop repeat 10 collect (cons 0 0)))))))