(in-package :ca.mhcat.advent2022)
;; --- Day 9: Rope Bridge ---
;; This rope bridge creaks as you walk along it. You aren't
;; sure how old it is, or whether it can even support your
;; weight.
;; It seems to support the Elves just fine, though. The
;; bridge spans a gorge which was carved out by the massive
;; river far below you.
;; You step carefully; as you do, the ropes stretch and
;; twist. You decide to distract yourself by modeling rope
;; physics; maybe you can even figure out where not to step.
;; Consider a rope with a knot at each end; these knots mark
;; the head and the tail of the rope. If the head moves far
;; enough away from the tail, the tail is pulled toward the
;; head.
;; Due to nebulous reasoning involving Planck lengths, you
;; should be able to model the positions of the knots on a
;; two-dimensional grid. Then, by following a hypothetical
;; series of motions (your puzzle input) for the head, you
;; can determine how the tail will move.
;; Due to the aforementioned Planck lengths, the rope must
;; be quite short; in fact, the head (H) and tail (T) must
;; always be touching (diagonally adjacent and even
;; overlapping both count as touching):
;; ....
;; .TH.
;; ....
;; ....
;; .H..
;; ..T.
;; ....
;; ...
;; .H. (H covers T)
;; ...
;; If the head is ever two steps directly up, down, left, or
;; right from the tail, the tail must also move one step in
;; that direction so it remains close enough:
;; ..... ..... .....
;; .TH.. -> .T.H. -> ..TH.
;; ..... ..... .....
;; ... ... ...
;; .T. .T. ...
;; .H. -> ... -> .T.
;; ... .H. .H.
;; ... ... ...
;; Otherwise, if the head and tail aren't touching and
;; aren't in the same row or column, the tail always moves
;; one step diagonally to keep up:
;; ..... ..... .....
;; ..... ..H.. ..H..
;; ..H.. -> ..... -> ..T..
;; .T... .T... .....
;; ..... ..... .....
;; ..... ..... .....
;; ..... ..... .....
;; ..H.. -> ...H. -> ..TH.
;; .T... .T... .....
;; ..... ..... .....
;; You just need to work out where the tail goes as the head
;; follows a series of motions. Assume the head and the tail
;; both start at the same position, overlapping.
;; For example:
;; R 4
;; U 4
;; L 3
;; D 1
;; R 4
;; D 1
;; L 5
;; R 2
(defparameter day9/test-data
'("R 4"
"U 4"
"L 3"
"D 1"
"R 4"
"D 1"
"L 5"
"R 2"))
(defun day9/parse-data (lines)
(mapcar (lambda (line)
(with-input-from-string (s line)
(list (read s) (read s))))
lines))
;; This series of motions moves the head right four steps,
;; then up four steps, then left three steps, then down one
;; step, and so on. After each step, you'll need to update
;; the position of the tail if the step means the head is no
;; longer adjacent to the tail. Visually, these motions
;; occur as follows (s marks the starting position as a
;; reference point):
;; == Initial State ==
;; ......
;; ......
;; ......
;; ......
;; H..... (H covers T, s)
;; == R 4 ==
;; ......
;; ......
;; ......
;; ......
;; TH.... (T covers s)
;; ......
;; ......
;; ......
;; ......
;; sTH...
;; ......
;; ......
;; ......
;; ......
;; s.TH..
;; ......
;; ......
;; ......
;; ......
;; s..TH.
;; == U 4 ==
;; ......
;; ......
;; ......
;; ....H.
;; s..T..
;; ......
;; ......
;; ....H.
;; ....T.
;; s.....
;; ......
;; ....H.
;; ....T.
;; ......
;; s.....
;; ....H.
;; ....T.
;; ......
;; ......
;; s.....
;; == L 3 ==
;; ...H..
;; ....T.
;; ......
;; ......
;; s.....
;; ..HT..
;; ......
;; ......
;; ......
;; s.....
;; .HT...
;; ......
;; ......
;; ......
;; s.....
;; == D 1 ==
;; ..T...
;; .H....
;; ......
;; ......
;; s.....
;; == R 4 ==
;; ..T...
;; ..H...
;; ......
;; ......
;; s.....
;; ..T...
;; ...H..
;; ......
;; ......
;; s.....
;; ......
;; ...TH.
;; ......
;; ......
;; s.....
;; ......
;; ....TH
;; ......
;; ......
;; s.....
;; == D 1 ==
;; ......
;; ....T.
;; .....H
;; ......
;; s.....
;; == L 5 ==
;; ......
;; ....T.
;; ....H.
;; ......
;; s.....
;; ......
;; ....T.
;; ...H..
;; ......
;; s.....
;; ......
;; ......
;; ..HT..
;; ......
;; s.....
;; ......
;; ......
;; .HT...
;; ......
;; s.....
;; ......
;; ......
;; HT....
;; ......
;; s.....
;; == R 2 ==
;; ......
;; ......
;; .H.... (H covers T)
;; ......
;; s.....
;; ......
;; ......
;; .TH...
;; ......
;; s.....
;; After simulating the rope, you can count up all of the
;; positions the tail visited at least once. In this
;; diagram, s again marks the starting position (which the
;; tail also visited) and # marks other positions the tail
;; visited:
;; ..##..
;; ...##.
;; .####.
;; ....#.
;; s###..
;; So, there are 13 positions the tail visited at least
;; once.
;; Simulate your complete hypothetical series of motions.
;; How many positions does the tail of the rope visit at
;; least once?
(defun day9/move-one (delta n)
(cond
((minusp delta) (1- n))
((plusp delta) (1+ n))
((zerop delta) n)
(t (error "poop"))))
(defun day9/move-tail (new-state old-state)
(destructuring-bind ((hdx hdy) (tlx tly) &rest rest) old-state
(let* ((xdelta (- hdx tlx))
(ydelta (- hdy tly))
(new-tl-hd
(if (and (<= (abs xdelta) 1) (<= (abs ydelta) 1))
;; do nothing case
(list tlx tly)
;; distance can only be 2
(list (day9/move-one xdelta tlx) (day9/move-one ydelta tly))))
(new-state (cons new-tl-hd new-state)))
(if rest
(day9/move-tail new-state (cons new-tl-hd rest))
(nreverse new-state)))))
(defun day9/next-state (move state)
(destructuring-bind ((hdx hdy) &rest rest) state
(let* ((delta (case move ((r u) 1) ((l d) -1)))
(new-hd (case move
((l r) (list (+ delta hdx) hdy))
((u d) (list hdx (+ delta hdy))))))
(day9/move-tail (list new-hd) (cons new-hd rest)))))
(defun day9/compute-one-instruction (inst initial-state)
(destructuring-bind (direction n) inst
(do ((batch nil)
(state initial-state (day9/next-state direction state))
(counter (1+ n) (1- counter)))
((zerop counter) batch)
(push state batch))))
(defun day9/compute-part1 (knot-count lst)
(let ((instructions (day9/parse-data lst))
(tl-places (list '(0 0))))
(reduce (lambda (state inst)
(let ((batch (day9/compute-one-instruction inst state)))
(loop for next in batch
do (pushnew (car (reverse next)) tl-places :test #'equal))
(car batch)))
instructions
:initial-value (make-list knot-count :initial-element (list 0 0)))
(length tl-places)))
(defun day9/part1 ()
(day9/compute-part1
2
(load-lines "day9.txt")))
;; --- Part Two ---
;; A rope snaps! Suddenly, the river is getting a lot closer
;; than you remember. The bridge is still there, but some of
;; the ropes that broke are now whipping toward you as you
;; fall through the air!
;; The ropes are moving too quickly to grab; you only have a
;; few seconds to choose how to arch your body to avoid
;; being hit. Fortunately, your simulation can be extended
;; to support longer ropes.
;; Rather than two knots, you now must simulate a rope
;; consisting of ten knots. One knot is still the head of
;; the rope and moves according to the series of motions.
;; Each knot further down the rope follows the knot in front
;; of it using the same rules as before.
;; Using the same series of motions as the above example,
;; but with the knots marked H, 1, 2, ..., 9, the motions
;; now occur as follows:
;; == Initial State ==
;; ......
;; ......
;; ......
;; ......
;; H..... (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
;; == R 4 ==
;; ......
;; ......
;; ......
;; ......
;; 1H.... (1 covers 2, 3, 4, 5, 6, 7, 8, 9, s)
;; ......
;; ......
;; ......
;; ......
;; 21H... (2 covers 3, 4, 5, 6, 7, 8, 9, s)
;; ......
;; ......
;; ......
;; ......
;; 321H.. (3 covers 4, 5, 6, 7, 8, 9, s)
;; ......
;; ......
;; ......
;; ......
;; 4321H. (4 covers 5, 6, 7, 8, 9, s)
;; == U 4 ==
;; ......
;; ......
;; ......
;; ....H.
;; 4321.. (4 covers 5, 6, 7, 8, 9, s)
;; ......
;; ......
;; ....H.
;; .4321.
;; 5..... (5 covers 6, 7, 8, 9, s)
;; ......
;; ....H.
;; ....1.
;; .432..
;; 5..... (5 covers 6, 7, 8, 9, s)
;; ....H.
;; ....1.
;; ..432.
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; == L 3 ==
;; ...H..
;; ....1.
;; ..432.
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ..H1..
;; ...2..
;; ..43..
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; .H1...
;; ...2..
;; ..43..
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; == D 1 ==
;; ..1...
;; .H.2..
;; ..43..
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; == R 4 ==
;; ..1...
;; ..H2..
;; ..43..
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ..1...
;; ...H.. (H covers 2)
;; ..43..
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ......
;; ...1H. (1 covers 2)
;; ..43..
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ......
;; ...21H
;; ..43..
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; == D 1 ==
;; ......
;; ...21.
;; ..43.H
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; == L 5 ==
;; ......
;; ...21.
;; ..43H.
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ......
;; ...21.
;; ..4H.. (H covers 3)
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ......
;; ...2..
;; ..H1.. (H covers 4; 1 covers 3)
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ......
;; ...2..
;; .H13.. (1 covers 4)
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ......
;; ......
;; H123.. (2 covers 4)
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; == R 2 ==
;; ......
;; ......
;; .H23.. (H covers 1; 2 covers 4)
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; ......
;; ......
;; .1H3.. (H covers 2, 4)
;; .5....
;; 6..... (6 covers 7, 8, 9, s)
;; Now, you need to keep track of the positions the new
;; tail, 9, visits. In this example, the tail never moves,
;; and so it only visits 1 position. However, be careful:
;; more types of motion are possible than before, so you
;; might want to visually compare your simulated rope to the
;; one above.
;; Here's a larger example:
;; R 5
;; U 8
;; L 8
;; D 3
;; R 17
;; D 10
;; L 25
;; U 20
(defparameter day9/test-data2
'("R 5"
"U 8"
"L 8"
"D 3"
"R 17"
"D 10"
"L 25"
"U 20"))
;; These motions occur as follows (individual steps are not
;; shown):
;; == Initial State ==
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ...........H.............. (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; == R 5 ==
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ...........54321H......... (5 covers 6, 7, 8, 9, s)
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; == U 8 ==
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ................H.........
;; ................1.........
;; ................2.........
;; ................3.........
;; ...............54.........
;; ..............6...........
;; .............7............
;; ............8.............
;; ...........9.............. (9 covers s)
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; == L 8 ==
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ........H1234.............
;; ............5.............
;; ............6.............
;; ............7.............
;; ............8.............
;; ............9.............
;; ..........................
;; ..........................
;; ...........s..............
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; == D 3 ==
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; .........2345.............
;; ........1...6.............
;; ........H...7.............
;; ............8.............
;; ............9.............
;; ..........................
;; ..........................
;; ...........s..............
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; == R 17 ==
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ................987654321H
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ...........s..............
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; == D 10 ==
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ...........s.........98765
;; .........................4
;; .........................3
;; .........................2
;; .........................1
;; .........................H
;; == L 25 ==
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ...........s..............
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; H123456789................
;; == U 20 ==
;; H.........................
;; 1.........................
;; 2.........................
;; 3.........................
;; 4.........................
;; 5.........................
;; 6.........................
;; 7.........................
;; 8.........................
;; 9.........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ...........s..............
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; Now, the tail (9) visits 36 positions (including s) at
;; least once:
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; ..........................
;; #.........................
;; #.............###.........
;; #............#...#........
;; .#..........#.....#.......
;; ..#..........#.....#......
;; ...#........#.......#.....
;; ....#......s.........#....
;; .....#..............#.....
;; ......#............#......
;; .......#..........#.......
;; ........#........#........
;; .........########.........
;; Simulate your complete series of motions on a larger rope
;; with ten knots. How many positions does the tail of the
;; rope visit at least once?
(defun day9/part2 ()
(day9/compute-part1
10
(load-lines "day9.txt")))