2022-12-09 - Rope Bridge
(original .ipynb)
Day 9 puzzle input is a sequence of move instructions - up/down/left/right + a distance - (mine is here). Part 1 involves taking a rope of length two units (well "knots" but w/e) and moving it around, noting how many unique positions the tail sits in. Part 2 is the same, but for a rope of length ten units/knots.
puzzle_input_str = open("./puzzle_input/day9.txt").read() test_input_str = """R 4 U 4 L 3 D 1 R 4 D 1 L 5 R 2""" moves = { "U": (-1, 0), "D": ( 1, 0), "L": ( 0, -1), "R": ( 0, 1) } def parse_lines(lines): for line in lines: direction, moves_str = line.split(" ") yield direction, int(moves_str) def move(pos, dr, dc): r, c = pos return (r+dr, c+dc) def should_move_knot(hr, hc, tr, tc): return abs(hr-tr) > 1 or abs(hc-tc) > 1 def tail_move(hr, hc, tr, tc): if should_move_knot(hr, hc, tr, tc): dr = hr - tr dc = hc - tc return ( 0 if dr == 0 else dr//abs(dr), 0 if dc == 0 else dc//abs(dc) ) return (0, 0) def part_one(input_str, knot_count=2): knots = [(0,0) for _ in range(knot_count)] tail_visited = {(0,0)} for direction, distance in parse_lines(input_str.splitlines()): dr, dc = moves[direction] while distance > 0: next_knots = [] for i, knot in enumerate(knots): if i == 0: knot = move(knot, dr, dc) else: knot = move(knot, *tail_move(*next_knots[i-1], *knot)) if i+1 == knot_count: tail_visited.add(knot) next_knots.append(knot) knots = next_knots distance -= 1 return len(tail_visited) assert 13 == part_one(test_input_str) print("part one:", part_one(puzzle_input_str))
part one: 6339
test_input_str_2 = """R 5 U 8 L 8 D 3 R 17 D 10 L 25 U 20""" def part_two(input_str): return part_one(input_str, 10) assert 36 == part_two(test_input_str_2) print("part two:", part_two(puzzle_input_str))
part two: 2541