Solution to first part of problem 10 in Python
This commit is contained in:
parent
ff58058928
commit
36d2884753
186
src/Year_2023/Day10.py
Normal file
186
src/Year_2023/Day10.py
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
# --- Day 10: Pipe Maze ---
|
||||||
|
|
||||||
|
# You use the hang glider to ride the hot air from Desert Island all the way up
|
||||||
|
# to the floating metal island. This island is surprisingly cold and there
|
||||||
|
# definitely aren't any thermals to glide on, so you leave your hang glider
|
||||||
|
# behind.
|
||||||
|
|
||||||
|
# You wander around for a while, but you don't find any people or animals.
|
||||||
|
# However, you do occasionally find signposts labeled "Hot Springs" pointing in
|
||||||
|
# a seemingly consistent direction; maybe you can find someone at the hot
|
||||||
|
# springs and ask them where the desert-machine parts are made.
|
||||||
|
|
||||||
|
# The landscape here is alien; even the flowers and trees are made of metal. As
|
||||||
|
# you stop to admire some metal grass, you notice something metallic scurry away
|
||||||
|
# in your peripheral vision and jump into a big pipe! It didn't look like any
|
||||||
|
# animal you've ever seen; if you want a better look, you'll need to get ahead
|
||||||
|
# of it.
|
||||||
|
|
||||||
|
# Scanning the area, you discover that the entire field you're standing on is
|
||||||
|
# densely packed with pipes; it was hard to tell at first because they're the
|
||||||
|
# same metallic silver color as the "ground". You make a quick sketch of all of
|
||||||
|
# the surface pipes you can see (your puzzle input).
|
||||||
|
|
||||||
|
# The pipes are arranged in a two-dimensional grid of tiles:
|
||||||
|
|
||||||
|
# | is a vertical pipe connecting north and south.
|
||||||
|
# - is a horizontal pipe connecting east and west.
|
||||||
|
# L is a 90-degree bend connecting north and east.
|
||||||
|
# J is a 90-degree bend connecting north and west.
|
||||||
|
# 7 is a 90-degree bend connecting south and west.
|
||||||
|
# F is a 90-degree bend connecting south and east.
|
||||||
|
# . is ground; there is no pipe in this tile.
|
||||||
|
# S is the starting position of the animal; there is a pipe on this tile,
|
||||||
|
# but your sketch doesn't show what shape the pipe has.
|
||||||
|
|
||||||
|
# Based on the acoustics of the animal's scurrying, you're confident the pipe
|
||||||
|
# that contains the animal is one large, continuous loop.
|
||||||
|
|
||||||
|
# For example, here is a square loop of pipe:
|
||||||
|
|
||||||
|
# .....
|
||||||
|
# .F-7.
|
||||||
|
# .|.|.
|
||||||
|
# .L-J.
|
||||||
|
# .....
|
||||||
|
|
||||||
|
# If the animal had entered this loop in the northwest corner, the sketch would
|
||||||
|
# instead look like this:
|
||||||
|
|
||||||
|
# .....
|
||||||
|
# .S-7.
|
||||||
|
# .|.|.
|
||||||
|
# .L-J.
|
||||||
|
# .....
|
||||||
|
|
||||||
|
# In the above diagram, the S tile is still a 90-degree F bend: you can tell
|
||||||
|
# because of how the adjacent pipes connect to it.
|
||||||
|
|
||||||
|
# Unfortunately, there are also many pipes that aren't connected to the loop!
|
||||||
|
# This sketch shows the same loop as above:
|
||||||
|
|
||||||
|
# -L|F7
|
||||||
|
# 7S-7|
|
||||||
|
# L|7||
|
||||||
|
# -L-J|
|
||||||
|
# L|-JF
|
||||||
|
|
||||||
|
# In the above diagram, you can still figure out which pipes form the main loop:
|
||||||
|
# they're the ones connected to S, pipes those pipes connect to, pipes those
|
||||||
|
# pipes connect to, and so on. Every pipe in the main loop connects to its two
|
||||||
|
# neighbors (including S, which will have exactly two pipes connecting to it,
|
||||||
|
# and which is assumed to connect back to those two pipes).
|
||||||
|
|
||||||
|
# Here is a sketch that contains a slightly more complex main loop:
|
||||||
|
|
||||||
|
# ..F7.
|
||||||
|
# .FJ|.
|
||||||
|
# SJ.L7
|
||||||
|
# |F--J
|
||||||
|
# LJ...
|
||||||
|
|
||||||
|
# Here's the same example sketch with the extra, non-main-loop pipe tiles also
|
||||||
|
# shown:
|
||||||
|
|
||||||
|
# 7-F7-
|
||||||
|
# .FJ|7
|
||||||
|
# SJLL7
|
||||||
|
# |F--J
|
||||||
|
# LJ.LJ
|
||||||
|
|
||||||
|
# If you want to get out ahead of the animal, you should find the tile in the
|
||||||
|
# loop that is farthest from the starting position. Because the animal is in the
|
||||||
|
# pipe, it doesn't make sense to measure this by direct distance. Instead, you
|
||||||
|
# need to find the tile that would take the longest number of steps along the
|
||||||
|
# loop to reach from the starting point - regardless of which way around the
|
||||||
|
# loop the animal went.
|
||||||
|
|
||||||
|
# In the first example with the square loop:
|
||||||
|
|
||||||
|
# .....
|
||||||
|
# .S-7.
|
||||||
|
# .|.|.
|
||||||
|
# .L-J.
|
||||||
|
# .....
|
||||||
|
|
||||||
|
# You can count the distance each tile in the loop is from the starting point
|
||||||
|
# like this:
|
||||||
|
|
||||||
|
# .....
|
||||||
|
# .012.
|
||||||
|
# .1.3.
|
||||||
|
# .234.
|
||||||
|
# .....
|
||||||
|
|
||||||
|
# In this example, the farthest point from the start is 4 steps away.
|
||||||
|
|
||||||
|
# Here's the more complex loop again:
|
||||||
|
|
||||||
|
# ..F7.
|
||||||
|
# .FJ|.
|
||||||
|
# SJ.L7
|
||||||
|
# |F--J
|
||||||
|
# LJ...
|
||||||
|
|
||||||
|
# Here are the distances for each tile on that loop:
|
||||||
|
|
||||||
|
# ..45.
|
||||||
|
# .236.
|
||||||
|
# 01.78
|
||||||
|
# 14567
|
||||||
|
# 23...
|
||||||
|
|
||||||
|
# Find the single giant loop starting at S. How many steps along the loop does
|
||||||
|
# it take to get from the starting position to the point farthest from the
|
||||||
|
# starting position?
|
||||||
|
|
||||||
|
with open("files/P10.txt") as f:
|
||||||
|
p = [row for row in f.read().strip().split("\n")]
|
||||||
|
|
||||||
|
|
||||||
|
def bfs(grid, directions, connections):
|
||||||
|
start = [pos for pos, c in grid.items() if c == "S"][0]
|
||||||
|
queue, seen = [(0, start)], set()
|
||||||
|
while queue:
|
||||||
|
count, (x, y) = queue.pop(0)
|
||||||
|
seen.add((x, y))
|
||||||
|
for dx, dy in directions[grid[x, y]]:
|
||||||
|
new_x, new_y = x + dx, y + dy
|
||||||
|
if (new_x, new_y) not in grid or (new_x, new_y) in seen:
|
||||||
|
continue
|
||||||
|
if grid[new_x, new_y] not in connections[dx, dy]:
|
||||||
|
continue
|
||||||
|
queue.append((count + 1, (new_x, new_y)))
|
||||||
|
return count, seen
|
||||||
|
|
||||||
|
|
||||||
|
def part1():
|
||||||
|
N, S, W, E = (0, -1), (0, 1), (-1, 0), (1, 0)
|
||||||
|
directions = {
|
||||||
|
"S": [N, S, W, E],
|
||||||
|
"|": [N, S],
|
||||||
|
"-": [E, W],
|
||||||
|
"L": [N, E],
|
||||||
|
"J": [N, W],
|
||||||
|
"7": [S, W],
|
||||||
|
"F": [S, E],
|
||||||
|
}
|
||||||
|
connections = {
|
||||||
|
N: {"|", "7", "F"},
|
||||||
|
S: {"|", "L", "J"},
|
||||||
|
E: {"-", "J", "7"},
|
||||||
|
W: {"-", "L", "F"},
|
||||||
|
}
|
||||||
|
grid = {
|
||||||
|
(x, y): c
|
||||||
|
for y, row in enumerate(p)
|
||||||
|
for x, c in enumerate(row)
|
||||||
|
if c != "."
|
||||||
|
}
|
||||||
|
total, _ = bfs(grid, directions, connections)
|
||||||
|
|
||||||
|
print(f"You need {total} steps")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
part1()
|
Loading…
x
Reference in New Issue
Block a user