def _navigate(ins: str, start: Position, in_bounds) -> NavigationWithHeading: navigation = NavigationWithHeading(start, Headings["N"].value, in_bounds) for i in range(len(ins)): step = ins[i] if step == 'R': navigation.drift(Headings["E"].value, 1) elif step == 'L': navigation.drift(Headings["W"].value, 1) elif step == 'U': navigation.drift(Headings["N"].value, 1) elif step == 'D': navigation.drift(Headings["S"].value, 1) else: raise ValueError("Invalid input") return navigation
def _add_navigation_instruction(navigation: NavigationWithHeading, c: str): if c == ">": navigation.drift(EAST, 1) elif c == "v": navigation.drift(SOUTH, 1) elif c == "<": navigation.drift(WEST, 1) elif c == "^": navigation.drift(NORTH, 1) else: raise ValueError("Invalid input")
def part_1(inputs: tuple[str]) -> int: navs = _parse(inputs) start = EAST navigation = NavigationWithHeading(position=Position(0, 0), heading=Headings[start].value) log(navigation) for nav in navs: _navigate_with_heading(navigation, nav) log(navigation) return abs(navigation.position.x) + abs(navigation.position.y)
def _navigate_with_heading(navigation: NavigationWithHeading, nav: NavigationInstruction) -> None: if nav.action == RIGHT: navigation.right(nav.value) elif nav.action == LEFT: navigation.left(nav.value) elif nav.action == FORWARD: navigation.forward(nav.value) elif nav.action in {NORTH, EAST, SOUTH, WEST}: navigation.drift(heading=Headings[nav.action].value, amount=nav.value) else: raise ValueError("invalid input")
def part_2(inputs: tuple[str]) -> int: assert len(inputs) == 1 santa_navigation = NavigationWithHeading(Position(0, 0), NORTH) robot_navigation = NavigationWithHeading(Position(0, 0), NORTH) for i, c in enumerate(inputs[0]): if i % 2 != 0: _add_navigation_instruction(robot_navigation, c) else: _add_navigation_instruction(santa_navigation, c) visited = santa_navigation.get_visited_positions(True) visited.extend(robot_navigation.get_visited_positions(True)) return _count_unique_positions(visited)
def part_1(inputs: tuple[str]) -> int: assert len(inputs) == 1 navigation = NavigationWithHeading(Position(0, 0), NORTH) for c in inputs[0]: _add_navigation_instruction(navigation, c) return _count_unique_positions(navigation.get_visited_positions(True))
def test_navigation_with_heading(self): navigation = NavigationWithHeading( Position(0, 0), Headings["N"].value, lambda pos: pos.x <= 4 and pos.y <= 4) navigation.drift(Headings["N"].value, 1) navigation.left(90) navigation.forward(1) navigation.right(180) navigation.forward(10) self.assertEqual(navigation.position, Position(4, 1)) visited_positions = navigation.get_visited_positions(True) self.assertEqual( visited_positions, [Position(0, 0), Position(0, 1), Position(-1, 1), Position(4, 1)]) visited_positions = navigation.get_visited_positions(False) self.assertEqual( visited_positions, [Position(0, 1), Position(-1, 1), Position(4, 1)])