Solution for problem 1 in Python
This commit is contained in:
parent
4d5a608c51
commit
4de3489f00
168
src/Year_2016/P1.py
Normal file
168
src/Year_2016/P1.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user