Solution to problem 13 in Python
This commit is contained in:
parent
ccb30f0893
commit
55898c1e1c
126
src/Year_2016/P13.py
Normal file
126
src/Year_2016/P13.py
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
# --- Day 13: A Maze of Twisty Little Cubicles ---
|
||||||
|
|
||||||
|
# You arrive at the first floor of this new building to discover a much
|
||||||
|
# less welcoming environment than the shiny atrium of the last one.
|
||||||
|
# Instead, you are in a maze of twisty little cubicles, all alike.
|
||||||
|
|
||||||
|
# Every location in this area is addressed by a pair of non-negative
|
||||||
|
# integers (x,y). Each such coordinate is either a wall or an open space.
|
||||||
|
# You can't move diagonally. The cube maze starts at 0,0 and seems to
|
||||||
|
# extend infinitely toward positive x and y; negative values are invalid,
|
||||||
|
# as they represent a location outside the building. You are in a small
|
||||||
|
# waiting area at 1,1.
|
||||||
|
|
||||||
|
# While it seems chaotic, a nearby morale-boosting poster explains, the
|
||||||
|
# layout is actually quite logical. You can determine whether a given x,y
|
||||||
|
# coordinate will be a wall or an open space using a simple system:
|
||||||
|
|
||||||
|
# Find x*x + 3*x + 2*x*y + y + y*y.
|
||||||
|
# Add the office designer's favorite number (your puzzle input).
|
||||||
|
# Find the binary representation of that sum; count the number of bits
|
||||||
|
# that are 1.
|
||||||
|
# If the number of bits that are 1 is even, it's an open space.
|
||||||
|
# If the number of bits that are 1 is odd, it's a wall.
|
||||||
|
|
||||||
|
# For example, if the office designer's favorite number were 10, drawing
|
||||||
|
# walls as # and open spaces as ., the corner of the building containing
|
||||||
|
# 0,0 would look like this:
|
||||||
|
|
||||||
|
# 0123456789
|
||||||
|
# 0 .#.####.##
|
||||||
|
# 1 ..#..#...#
|
||||||
|
# 2 #....##...
|
||||||
|
# 3 ###.#.###.
|
||||||
|
# 4 .##..#..#.
|
||||||
|
# 5 ..##....#.
|
||||||
|
# 6 #...##.###
|
||||||
|
|
||||||
|
# Now, suppose you wanted to reach 7,4. The shortest route you could take
|
||||||
|
# is marked as O:
|
||||||
|
|
||||||
|
# 0123456789
|
||||||
|
# 0 .#.####.##
|
||||||
|
# 1 .O#..#...#
|
||||||
|
# 2 #OOO.##...
|
||||||
|
# 3 ###O#.###.
|
||||||
|
# 4 .##OO#OO#.
|
||||||
|
# 5 ..##OOO.#.
|
||||||
|
# 6 #...##.###
|
||||||
|
|
||||||
|
# Thus, reaching 7,4 would take a minimum of 11 steps (starting from your
|
||||||
|
# current location, 1,1).
|
||||||
|
|
||||||
|
# What is the fewest number of steps required for you to reach 31,39?
|
||||||
|
|
||||||
|
# Your puzzle input is 1350.
|
||||||
|
|
||||||
|
inp = 1350
|
||||||
|
destination = (31, 39)
|
||||||
|
size = 100
|
||||||
|
|
||||||
|
|
||||||
|
def is_wall(x: int, y: int) -> bool:
|
||||||
|
res = inp + (x * x + 3 * x + 2 * x * y + y + y * y)
|
||||||
|
return format(res, "b").count("1") % 2
|
||||||
|
|
||||||
|
|
||||||
|
def part_1() -> None:
|
||||||
|
visited = {(1, 1)}
|
||||||
|
steps = 0
|
||||||
|
|
||||||
|
while visited:
|
||||||
|
places_to_check = visited.copy()
|
||||||
|
visited = set()
|
||||||
|
for dx, dy in places_to_check:
|
||||||
|
# neighboring points to the current point (left, right, up, and down)
|
||||||
|
for x, y in [
|
||||||
|
(dx + 1, dy),
|
||||||
|
(dx - 1, dy),
|
||||||
|
(dx, dy + 1),
|
||||||
|
(dx, dy - 1),
|
||||||
|
]:
|
||||||
|
if x < 0 or y < 0 or (x, y) in visited or is_wall(x, y):
|
||||||
|
continue
|
||||||
|
visited.add((x, y))
|
||||||
|
steps += 1
|
||||||
|
|
||||||
|
if destination in visited:
|
||||||
|
print(steps)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
# --- Part Two ---
|
||||||
|
|
||||||
|
# How many locations (distinct x,y coordinates, including
|
||||||
|
# your starting location) can you reach in at most 50 steps?
|
||||||
|
|
||||||
|
|
||||||
|
def part_2() -> None:
|
||||||
|
visited = traversed = {(1, 1)}
|
||||||
|
steps = 0
|
||||||
|
|
||||||
|
while visited:
|
||||||
|
places_to_check = visited.copy()
|
||||||
|
visited = set()
|
||||||
|
for dx, dy in places_to_check:
|
||||||
|
# neighboring points to the current point (left, right, up, and down)
|
||||||
|
for x, y in [
|
||||||
|
(dx + 1, dy),
|
||||||
|
(dx - 1, dy),
|
||||||
|
(dx, dy + 1),
|
||||||
|
(dx, dy - 1),
|
||||||
|
]:
|
||||||
|
if x < 0 or y < 0 or (x, y) in visited or is_wall(x, y):
|
||||||
|
continue
|
||||||
|
visited.add((x, y))
|
||||||
|
traversed.add((x, y))
|
||||||
|
steps += 1
|
||||||
|
|
||||||
|
if steps == 50:
|
||||||
|
print(len(traversed))
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
part_1()
|
||||||
|
part_2()
|
Loading…
x
Reference in New Issue
Block a user