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…
x
Reference in New Issue
Block a user