# [Advent Of Code 2022] Day 9: Rope Bridge [SPOILERS]

Ruby Solution
``````require 'set'

def num_visited(num_knots)
knots = Array.new(num_knots) { [0, 0] }
visited = Set.new([knots.last.dup])

moves = File.readlines('inputs/09.txt', chomp: true).map { |line| line.split(' ').then { [_1, _2.to_i] } }
moves.each do |move, distance|
distance.times do
case move
when 'R' then knots += 1
when 'L' then knots -= 1
when 'U' then knots += 1
when 'D' then knots -= 1
end

if (leader - follower).abs > 1 || (leader - follower).abs > 1
end
end

visited << knots.last.dup
end
end

visited.size
end

a = num_visited(2)
b = num_visited(10)

require 'minitest/autorun'

describe 'day 09' do
it 'part a' do assert_equal 6_023, a end
it 'part b' do assert_equal 2_533, b end
end
``````
1 Like

I could use my `Pos` and `Delta` classes for the positions and movements of the knots.

Python Solution
``````directions = dict(zip('ULRD', dirs4))

def read_file(file: TextIO) -> list[tuple[Delta, int]]:
lines = (line.split() for line in file)
return [(directions[direction], int(steps)) for direction, steps in lines]

def move(knot: Pos, previous: Pos) -> Pos:
"""Calculate the new position of the knot, based on the previous knot."""
delta = previous - knot
assert delta.chessboard_length() <= 2
if delta.chessboard_length() <= 1:
return knot
return knot + Delta(dx=sign0(delta.dx), dy=sign0(delta.dy))

def count_nth_knot_positions(
motions: list[tuple[Delta, int]], length: int) -> int:
"""Count the different positions of the last knot during the `motions`."""
positions = set((origin, ))
knots = [origin] * length
for direction, count in motions:
for _ in range(count):
knots = knots + direction
for i in range(1, length):
knots[i] = move(knots[i], knots[i - 1])
return len(positions)

def part1(file: TextIO) -> int:
"""Solve the first part of the puzzle."""
return count_nth_knot_positions(motions, 2)

def part2(file: TextIO) -> int:
"""Solve the second part of the puzzle."""
return count_nth_knot_positions(motions, 10)
``````

Once again, using `complex` values for my points made my life so much simpler!

I did need to add a `cmp(a, b)` function to my library for this (returns `-1 | 0 | 1` based on `a < b | a == b | a > b`). Many languages have this built in.

Code: FinalJust Make It Work

Python Solution
``````    def solver(self, lines: list[tuple[str, int]], knot_count: int) -> int:
"""Track the movement of knots on a rope. Return the number of positions the tail visits."""
points: set[complex] = set()
knots: list[complex] =  * knot_count
movement = {"R": 1, "L": -1, "U": 1j, "D": -1j}
for direction, unit in lines:
for _ in range(unit):
knots += movement[direction]
for i, (a, b) in enumerate(zip(knots, knots[1:])):
if a - b in aoc.NEIGHBORS:
continue
x = self.cmp(a.real, b.real)
y = self.cmp(a.imag, b.imag)
knots[i + 1] += complex(x, y)