163 lines
5.7 KiB
Python
163 lines
5.7 KiB
Python
|
#!/bin/python3
|
||
|
import sys,time,re
|
||
|
from pprint import pprint
|
||
|
sys.path.insert(0, '../../')
|
||
|
from fred import list2int,get_re,nprint,lprint,loadFile,toGrid, get_value_in_direction,addTuples
|
||
|
start_time = time.time()
|
||
|
|
||
|
input_f = 'test2'
|
||
|
|
||
|
part = 1
|
||
|
#########################################
|
||
|
# #
|
||
|
# Part 1 #
|
||
|
# #
|
||
|
#########################################
|
||
|
|
||
|
if part == 1:
|
||
|
|
||
|
|
||
|
def get_value_in_direction(grid, position, direction=None, length=1, type: str = None):
|
||
|
"""
|
||
|
Get the value(s) in a specified direction from a given position in a grid.
|
||
|
If no direction is provided, returns the value at the current position.
|
||
|
|
||
|
Args:
|
||
|
grid (list of list of int/float/str): The 2D grid.
|
||
|
position (set): A set containing x (row index) and y (column index) as integers.
|
||
|
direction (str, optional): The direction to check. Defaults to None.
|
||
|
length (int, optional): The number of steps to check in the given direction. Default is 1.
|
||
|
type (str, optional): The type of result to return ('list' or 'str'). Defaults to None.
|
||
|
|
||
|
Returns:
|
||
|
list or str: A list or string of values in the specified direction, or a single value.
|
||
|
|
||
|
Raises:
|
||
|
ValueError: If direction is invalid or position is not a set of two integers.
|
||
|
TypeError: If grid is not a list of lists.
|
||
|
"""
|
||
|
if not all(isinstance(row, list) for row in grid):
|
||
|
raise TypeError("Grid must be a list of lists.")
|
||
|
|
||
|
# Ensure position is a set of two integers
|
||
|
if len(position) != 2 or not all(isinstance(coord, int) for coord in position):
|
||
|
raise ValueError("Position must be a set containing two integers (x, y).")
|
||
|
|
||
|
x, y = position
|
||
|
offsets = {
|
||
|
'up': (-1, 0),
|
||
|
'down': (1, 0),
|
||
|
'left': (0, -1),
|
||
|
'right': (0, 1),
|
||
|
'up-left': (-1, -1),
|
||
|
'up-right': (-1, 1),
|
||
|
'down-left': (1, -1),
|
||
|
'down-right': (1, 1)
|
||
|
}
|
||
|
|
||
|
# If no direction is given, return the value at the current position
|
||
|
if direction is None:
|
||
|
if 0 <= x < len(grid) and 0 <= y < len(grid[x]):
|
||
|
return grid[x][y]
|
||
|
else:
|
||
|
return None
|
||
|
|
||
|
# Validate direction
|
||
|
if direction not in offsets:
|
||
|
raise ValueError(f"Invalid direction: {direction}. Choose from {list(offsets.keys())}")
|
||
|
|
||
|
dx, dy = offsets[direction]
|
||
|
new_x, new_y = x + dx, y + dy
|
||
|
|
||
|
values = []
|
||
|
|
||
|
if length == 1:
|
||
|
# Check for out-of-bounds
|
||
|
if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[new_x]):
|
||
|
return grid[new_x][new_y]
|
||
|
else:
|
||
|
return None
|
||
|
else:
|
||
|
for step in range(length):
|
||
|
new_x, new_y = x + step * dx, y + step * dy
|
||
|
# Check for out-of-bounds
|
||
|
if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[new_x]):
|
||
|
values.append(grid[new_x][new_y])
|
||
|
else:
|
||
|
return [] # Return empty list if any position is out of bounds
|
||
|
if type == 'list':
|
||
|
return values
|
||
|
elif type == 'str':
|
||
|
return ''.join(values)
|
||
|
else:
|
||
|
return values
|
||
|
|
||
|
grid = toGrid(input_f,True)
|
||
|
|
||
|
def extract_tuples(nested_list):
|
||
|
result = []
|
||
|
for item in nested_list:
|
||
|
if isinstance(item, tuple): # Check if the item is a tuple
|
||
|
result.append(item)
|
||
|
elif isinstance(item, list): # If it's a list, recurse into it
|
||
|
result.extend(extract_tuples(item))
|
||
|
return result
|
||
|
|
||
|
def find_path(grid,pos:set,cur):
|
||
|
path = 0
|
||
|
if cur == 9:
|
||
|
return 1
|
||
|
|
||
|
cur+=1
|
||
|
|
||
|
|
||
|
if get_value_in_direction(grid,pos,'up') == cur:
|
||
|
path += find_path(grid,addTuples(pos,(-1,0)),cur)
|
||
|
|
||
|
if get_value_in_direction(grid,pos,'down') == cur:
|
||
|
path += find_path(grid,addTuples(pos,(1,0)),cur)
|
||
|
|
||
|
if get_value_in_direction(grid,pos,'left') == cur:
|
||
|
path += find_path(grid,addTuples(pos,(0,-1)),cur)
|
||
|
|
||
|
if get_value_in_direction(grid,pos,'right') == cur:
|
||
|
path += find_path(grid,addTuples(pos,(0,1)),cur)
|
||
|
|
||
|
|
||
|
return path
|
||
|
|
||
|
result = 0
|
||
|
|
||
|
for r, row in enumerate(grid):
|
||
|
for c, col in enumerate(row):
|
||
|
#get_value_in_direction(grid, position, direction=None, length=1, type: str = None):
|
||
|
if grid[r][c] == 0:
|
||
|
if get_value_in_direction(grid,(r,c),'up') == 1:
|
||
|
#print(find_path(grid,(r-1,c),1))
|
||
|
result += find_path(grid,(r-1,c),1)
|
||
|
|
||
|
if get_value_in_direction(grid,(r,c),'down') == 1:
|
||
|
result += find_path(grid,(r+1,c),1)
|
||
|
#print(find_path(grid,(r+1,c),1,0))
|
||
|
|
||
|
if get_value_in_direction(grid,(r,c),'left') == 1:
|
||
|
result += find_path(grid,(r,c-1),1)
|
||
|
#print(find_path(grid,(r,c-1),1,0))
|
||
|
|
||
|
if get_value_in_direction(grid,(r,c),'right') == 1:
|
||
|
result += find_path(grid,(r,c+1),1)
|
||
|
#print(find_path(grid,(r,c+1),1,0))
|
||
|
|
||
|
print(result)
|
||
|
|
||
|
|
||
|
#########################################
|
||
|
# #
|
||
|
# Part 2 #
|
||
|
# #
|
||
|
#########################################
|
||
|
if part == 2:
|
||
|
exit()
|
||
|
|
||
|
print("--- %s seconds ---" % (time.time() - start_time))
|