From 55898c1e1c18ff58b7d4b1c068d3037602717579 Mon Sep 17 00:00:00 2001 From: daviddoji Date: Sat, 29 Apr 2023 15:37:33 +0200 Subject: [PATCH] Solution to problem 13 in Python --- src/Year_2016/P13.py | 126 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/Year_2016/P13.py diff --git a/src/Year_2016/P13.py b/src/Year_2016/P13.py new file mode 100644 index 0000000..127c7e9 --- /dev/null +++ b/src/Year_2016/P13.py @@ -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()