116 lines
3.6 KiB
Python

# --- 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()