Solution to problem 13 in Python

This commit is contained in:
David Doblas Jiménez 2023-04-29 15:37:33 +02:00
parent ccb30f0893
commit 55898c1e1c

126
src/Year_2016/P13.py Normal file
View 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()