AdventOfCode/fred.py

191 lines
5.5 KiB
Python

import re,sys
def loadFile(input_f):
lines = []
with open(input_f) as file:
for line in file:
lines.append(line.rstrip())
return lines
def convert_list(input_list):
"""
Convert a list of strings to integers where possible, leaving others as strings.
Args:
input_list (list): A list of strings to be converted.
Returns:
list: A list with integers or strings based on the input.
"""
converted_list = []
for item in input_list:
try:
converted_list.append(int(item))
except ValueError:
converted_list.append(item)
return converted_list
def toGrid(input,parser=None):
grid = []
if parser:
with open(input) as file:
for line in file:
grid.append(list2int(line.rstrip()))
else:
with open(input) as file:
for line in file:
grid.append(list(line.rstrip()))
return grid
def swap(a:int,b:int,lst:list):
"""
Swaps two numbers in a list based on their indices.
Parameters:
lst (list): The list of numbers.
index1 (int): The index of the first number.
index2 (int): The index of the second number.
Returns:
list: The list after swapping the two numbers.
"""
if a < 0 or b < 0 or a >= len(lst) or b >= len(lst):
raise IndexError("Index out of range.")
lst[a], lst[b] = lst[b], lst[a]
return lst
def addTuples(x:tuple,y:tuple):
return (x[0]+y[0],x[1]+y[1])
def findDupes(input:list):
# Returns the indicies of duplicate values in list
return [item for item in set(input) if input.count(item) > 1]
def lprint(x:str,log:bool):
if log:
print(x)
def expand_grid(grid):
num_rows = len(grid)
num_cols = len(grid[0])
expanded_grid = []
expanded_grid.append(['.'] * (num_cols + 2))
for row in grid:
expanded_grid.append(['.'] + row + ['.'])
expanded_grid.append(['.'] * (num_cols + 2))
return expanded_grid
def getCenter(grid):
return (int(len(grid)/2),int(len(grid[0])/2))
def nprint(grid,cur:set=None,sign:str=None):
for idx,i in enumerate(grid):
for jdx,j in enumerate(i):
if (idx,jdx) == cur:
if len(sign) > 1:
print(sign[0]+grid[idx][jdx]+sign[1],end='')
else:
print(sign,end=' ')
else:
print(grid[idx][jdx],end=' ')
print()
def list2int(x):
return list(map(int, x))
def grid_valid(x,y,grid):
rows = len(grid)
cols = len(grid[0])
return 0 <= x < rows and 0 <= y < cols
def get_re(pattern,str):
match = re.match(pattern, str)
if match:
return match
return None
def ppprint(x):
for idx,i in enumerate(x):
for jdx,j in enumerate(i):
print(x[idx][jdx],end='')
print()
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.
Parameters:
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.
Options: 'up', 'down', 'left', 'right',
'up-left', 'up-right', 'down-left', 'down-right'.
length (int, optional): The number of steps to check in the given direction. Default is 1.
Returns:
list: A list of values in the grid for the specified direction and length.
Returns an empty list if any position is out of bounds.
"""
# Ensure the 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, considering varying row lengths
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):
print(step)
new_x, new_y = x + step * dx, y + step * dy
# Check for out-of-bounds, considering varying row lengths
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