Solution for problem 1 in Python

This commit is contained in:
David Doblas Jiménez 2022-02-25 10:53:46 +01:00
parent 4d5a608c51
commit 4de3489f00

168
src/Year_2016/P1.py Normal file
View File

@ -0,0 +1,168 @@
# --- Day 1: No Time for a Taxicab ---
# Santa's sleigh uses a very high-precision clock to guide its movements, and
# the clock's oscillator is regulated by stars. Unfortunately, the stars have
# been stolen... by the Easter Bunny. To save Christmas, Santa needs you to
# retrieve all fifty stars by December 25th.
# Collect stars by solving puzzles. Two puzzles will be made available on each
# day in the Advent calendar; the second puzzle is unlocked when you complete
# the first. Each puzzle grants one star. Good luck!
# You're airdropped near Easter Bunny Headquarters in a city somewhere. "Near",
# unfortunately, is as close as you can get - the instructions on the Easter
# Bunny Recruiting Document the Elves intercepted start here, and nobody had
# time to work them out further.
# The Document indicates that you should start at the given coordinates (where
# you just landed) and face North. Then, follow the provided sequence: either
# turn left (L) or right (R) 90 degrees, then walk forward the given number of blocks, ending at a new intersection.
# There's no time to follow such ridiculous instructions on foot, though, so
# you take a moment and work out the destination. Given that you can only walk
# on the street grid of the city, how far is the shortest path to the
# destination?
# For example:
# Following R2, L3 leaves you 2 blocks East and 3 blocks North, or 5 blocks
# away.
# R2, R2, R2 leaves you 2 blocks due South of your starting position, which
# is 2 blocks away.
# R5, L5, R5, R3 leaves you 12 blocks away.
# How many blocks away is Easter Bunny HQ?
from typing import Any, List, Optional, Tuple
with open("files/P1.txt") as f:
coords = [seq for seq in f.read().strip().split(", ")]
def part_1() -> None:
init: List[Any] = ["N", 0, 0]
for coord in coords:
turn, steps = coord[0], int(coord[1:])
if init[0] == "N" and turn == "R":
init = ["E", init[1] + steps, init[2]]
elif init[0] == "N" and turn == "L":
init = ["W", init[1] - steps, init[2]]
elif init[0] == "S" and turn == "R":
init = ["W", init[1] - steps, init[2]]
elif init[0] == "S" and turn == "L":
init = ["E", init[1] + steps, init[2]]
elif init[0] == "W" and turn == "R":
init = ["N", init[1], init[2] + steps]
elif init[0] == "W" and turn == "L":
init = ["S", init[1], init[2] - steps]
elif init[0] == "E" and turn == "R":
init = ["S", init[1], init[2] - steps]
elif init[0] == "E" and turn == "L":
init = ["N", init[1], init[2] + steps]
end = abs(init[1]) + abs(init[2])
print(f"Easter Bunny HQ is {end} blocks away")
# --- Part Two ---
# Then, you notice the instructions continue on the back of the Recruiting
# Document. Easter Bunny HQ is actually at the first location you visit twice.
# For example, if your instructions are R8, R4, R4, R8, the first location you
# visit twice is 4 blocks away, due East.
# How many blocks away is the first location you visit twice?
def find_first_duplicate(
lst: List[Tuple[int, int]]
) -> Optional[Tuple[int, int]]:
set_ = set()
for item in lst:
if item in set_:
return item
set_.add(item)
return None
def part_2() -> None:
init: List[Any] = ["N", 0, 0]
visited: List[Tuple[int, int]] = [(0, 0)]
for coord in coords:
turn, steps = coord[0], int(coord[1:])
if init[0] == "N" and turn == "R":
visited = visited + [
(visited[-1][0] + step, visited[-1][1])
for step in range(1, steps + 1)
]
init = ["E", init[1] + steps, init[2]]
if find_first_duplicate(visited):
break
elif init[0] == "N" and turn == "L":
visited = visited + [
(visited[-1][0] - step, visited[-1][1])
for step in range(1, steps + 1)
]
init = ["W", init[1] - steps, init[2]]
if find_first_duplicate(visited):
break
elif init[0] == "S" and turn == "R":
visited = visited + [
(visited[-1][0] - step, visited[-1][1])
for step in range(1, steps + 1)
]
init = ["W", init[1] - steps, init[2]]
if find_first_duplicate(visited):
break
elif init[0] == "S" and turn == "L":
visited = visited + [
(visited[-1][0] + step, visited[-1][1])
for step in range(1, steps + 1)
]
init = ["E", init[1] + steps, init[2]]
if find_first_duplicate(visited):
break
elif init[0] == "W" and turn == "R":
visited = visited + [
(visited[-1][0], visited[-1][1] + step)
for step in range(1, steps + 1)
]
init = ["N", init[1], init[2] + steps]
if find_first_duplicate(visited):
break
elif init[0] == "W" and turn == "L":
visited = visited + [
(visited[-1][0], visited[-1][1] - step)
for step in range(1, steps + 1)
]
init = ["S", init[1], init[2] - steps]
if find_first_duplicate(visited):
break
elif init[0] == "E" and turn == "R":
visited = visited + [
(visited[-1][0], visited[-1][1] - step)
for step in range(1, steps + 1)
]
init = ["S", init[1], init[2] - steps]
if find_first_duplicate(visited):
break
elif init[0] == "E" and turn == "L":
visited = visited + [
(visited[-1][0], visited[-1][1] + step)
for step in range(1, steps + 1)
]
init = ["N", init[1], init[2] + steps]
if find_first_duplicate(visited):
break
twice = find_first_duplicate(visited)
end = abs(twice[0]) + abs(twice[1])
print(f"The location visited twice is {end} blocks away")
if __name__ == "__main__":
part_1()
part_2()