aboutsummaryrefslogtreecommitdiff
path: root/2022/Day09
diff options
context:
space:
mode:
authorSyndamia <kamen@syndamia.com>2022-12-10 13:14:37 +0200
committerSyndamia <kamen@syndamia.com>2022-12-10 13:14:37 +0200
commitbfd9c231ca46171b77a5912f0adb2f54ead904d1 (patch)
treef8fb0965a57bdc640d872f62c3706fc7bac94eeb /2022/Day09
parent92bd65ac086522ddea27f556085671040f8d7378 (diff)
downloadadvent-of-code-bfd9c231ca46171b77a5912f0adb2f54ead904d1.tar
advent-of-code-bfd9c231ca46171b77a5912f0adb2f54ead904d1.tar.gz
advent-of-code-bfd9c231ca46171b77a5912f0adb2f54ead904d1.zip
[2022/D09] Solved both tasks from today
Diffstat (limited to '2022/Day09')
-rw-r--r--2022/Day09/part-one.cl29
-rw-r--r--2022/Day09/part-two.cl47
2 files changed, 60 insertions, 16 deletions
diff --git a/2022/Day09/part-one.cl b/2022/Day09/part-one.cl
index 9e44aa0..f76fa8d 100644
--- a/2022/Day09/part-one.cl
+++ b/2022/Day09/part-one.cl
@@ -7,13 +7,10 @@
(ask-for-stream (prog-input)
(let ((rhead '(0 . 0)) (rtail '(0 . 0)) (visited '((0 . 0))) (movec '()))
- (flet ((p-longer-than-sqrt2 (c)
- "If c is outside the 3x3 square"
+ (flet ((norm>sqrt2p (c) ; If c's eucledian length is less than sqrt(2). In other words, if c is outside the 3x3 square.
+ "Optimized version of (> (norm p) (sqrt 2))"
(or (> (abs (car c)) 1) (> (abs (cdr c)) 1)))
- (movement-vec (c1 c2)
- (cons (- (car c2) (car c1)) (- (cdr c2) (cdr c1))))
-
(dir-to-pair (direction)
(cond ((char= direction #\R) '( 1 . 0))
((char= direction #\L) '(-1 . 0))
@@ -21,17 +18,17 @@
((char= direction #\D) '( 0 . -1)))))
(doread-lines (inpt :read-line-options (prog-input NIL))
- (pair+= rhead (*pair (digit-char-p (char inpt 2))
- (dir-to-pair (char inpt 0))))
+ (loop for i from 1 to (parse-integer inpt :start 2)
- (setf movec (movement-vec rtail rhead))
+ do
+ (pair+= rhead (dir-to-pair (char inpt 0)))
+ (setf movec (pair- rhead rtail))
- (if (p-longer-than-sqrt2 movec)
- (progn (setf movec (pair-round (dist-resize-by movec -1))) ; We dont want to move tail on the head, but behind it
- (pair+= rtail movec)
+ if (norm>sqrt2p movec)
+ do
+ ;; dist-resize so we don't put the knot on top of the head, but behind it
+ (pair+= rtail (pair-round (dist-resize-by movec -1)))
+ (if (not (member-if (lambda (x) (pair= x rtail)) visited))
+ (push rtail visited))))
- (loop for intermvec = movec then (pair-round (dist-resize-by intermvec -1))
- until (pair= intermvec '(0 . 0))
- if (not (member (pair- rtail intermvec) visited))
- do (push (pair- rtail intermvec) visited)))))
- (print visited))))
+ (print (length visited)))))
diff --git a/2022/Day09/part-two.cl b/2022/Day09/part-two.cl
new file mode 100644
index 0000000..06f6623
--- /dev/null
+++ b/2022/Day09/part-two.cl
@@ -0,0 +1,47 @@
+;;; https://gitlab.com/Syndamia/senzill
+(require :senzill)
+(use-package :senzill.math)
+(use-package :senzill.collections)
+(use-package :senzill.pair)
+(use-package :senzill.io)
+
+(defparameter +rope-length+ 10)
+
+(ask-for-stream (prog-input)
+ (let ((rope '()) (visited '((0 . 0))))
+ (flet ((norm>sqrt2p (p) ; If c's eucledian length is less than sqrt(2). In other words, if c is outside the 3x3 square.
+ "Optimized version of (> (norm p) (sqrt 2))"
+ (or (> (abs (car p)) 1) (> (abs (cdr p)) 1)))
+
+ (dir-to-pair (direction)
+ (cond ((char= direction #\R) '( 1 . 0))
+ ((char= direction #\L) '(-1 . 0))
+ ((char= direction #\U) '( 0 . 1))
+ ((char= direction #\D) '( 0 . -1)))))
+
+ (dotimes (i +rope-length+)
+ (push '(0 . 0) rope))
+
+ (doread-lines (inpt :read-line-options (prog-input NIL))
+ (loop for i from 1 to (parse-integer inpt :start 2)
+ for dirvec = (dir-to-pair (char inpt 0))
+
+ do
+ (pair+= (first rope) dirvec) ; First knot is the head
+ ;;; We update the knot positions from left to right (from head to tail)
+ ;;; Since each knot depends on the previous, we iterate from head to tail-1
+ ;;; but always update "the second element" (from head+1 to tail)
+ (loop for knot on rope
+ while (cdr knot)
+ for movec = (pair- (first knot) (second knot)) ; head - tail
+
+ if (norm>sqrt2p movec)
+ do
+ ;; dist-resize so we don't put the knot on top of the other, but behind it
+ (pair+= (second knot) (pair-round (dist-resize-by movec -1)))
+
+ finally
+ (if (not (member-if (lambda (x) (pair= x (car knot))) visited))
+ (push (car knot) visited)))))
+
+ (print (length visited)))))