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