# --- Day 3: Perfectly Spherical Houses in a Vacuum --- # Santa is delivering presents to an infinite two-dimensional grid of houses. # He begins by delivering a present to the house at his starting location, and # then an elf at the North Pole calls him via radio and tells him where to move # next. Moves are always exactly one house to the north (^), south (v), east # (>), or west (<). After each move, he delivers another present to the house # at his new location. # However, the elf back at the north pole has had a little too much eggnog, and # so his directions are a little off, and Santa ends up visiting some houses # more than once. How many houses receive at least one present? # For example: # > delivers presents to 2 houses: one at the starting location, and one to # the east. # ^>v< delivers presents to 4 houses in a square, including twice to the # house at his starting/ending location. # ^v^v^v^v^v delivers a bunch of presents to some very lucky children at # only 2 houses. from typing import Tuple with open("files/P3.txt") as f: moves = [line for line in f.read().strip().split()][0] def move_up(pos: Tuple[int, int]) -> Tuple[int, int]: return pos[0], pos[1] + 1 def move_down(pos: Tuple[int, int]) -> Tuple[int, int]: return pos[0], pos[1] - 1 def move_left(pos: Tuple[int, int]) -> Tuple[int, int]: return pos[0] - 1, pos[1] def move_right(pos: Tuple[int, int]) -> Tuple[int, int]: return pos[0] + 1, pos[1] def part_1() -> None: pos = [(0, 0)] for move in moves: if move == "^": pos.append(move_up(pos[-1])) elif move == "v": pos.append(move_down(pos[-1])) elif move == "<": pos.append(move_left(pos[-1])) elif move == ">": pos.append(move_right(pos[-1])) print(f"{len(set(pos))} houses receive at least one present") # --- Part Two --- # The next year, to speed up the process, Santa creates a robot version of # himself, Robo-Santa, to deliver presents with him. # Santa and Robo-Santa start at the same location (delivering two presents to # the same starting house), then take turns moving based on instructions from # the elf, who is eggnoggedly reading from the same script as the previous # year. # This year, how many houses receive at least one present? # For example: # ^v delivers presents to 3 houses, because Santa goes north, and then # Robo-Santa goes south. # ^>v< now delivers presents to 3 houses, and Santa and Robo-Santa end up # back where they started. # ^v^v^v^v^v now delivers presents to 11 houses, with Santa going one # direction and Robo-Santa going the other. def part_2(): santa = [(0, 0)] robo_santa = [(0, 0)] for idx, move in enumerate(moves): if move == "^": if idx % 2 == 0: santa.append(move_up(santa[-1])) else: robo_santa.append(move_up(robo_santa[-1])) elif move == "v": if idx % 2 == 0: santa.append(move_down(santa[-1])) else: robo_santa.append(move_down(robo_santa[-1])) elif move == "<": if idx % 2 == 0: santa.append(move_left(santa[-1])) else: robo_santa.append(move_left(robo_santa[-1])) elif move == ">": if idx % 2 == 0: santa.append(move_right(santa[-1])) else: robo_santa.append(move_right(robo_santa[-1])) print( f"{len(set(santa + robo_santa))} houses receive at least one present" ) if __name__ == "__main__": part_1() part_2()