116 lines
3.6 KiB
Python
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()
|