advent_of_code/25/4/main.py
2025-12-05 17:06:59 -06:00

79 lines
2.5 KiB
Python

def num_neighbours(lines: [], line_index: int, pos_index: int, num_lines: int, line_length: int) -> int:
'''Check surrounding and current row neighbours of a given position.
Does not operate on 2d coords directly, but on index and current versus prev/next lines.
'''
total = 0
for ii in range(max(0, line_index - 1), min(num_lines, line_index + 2)):
for jj in range(max(0, pos_index - 1), min(line_length, pos_index + 2)):
if ii == line_index and jj == pos_index:
continue
if lines[ii][jj] == '@':
total += 1
return total
def process_line(lines: []) -> int:
'''Iterate through all lines in the map and determine which can be removed this time around'''
total = 0
for line_index, line in enumerate(lines):
for index, char in enumerate(line):
if char == '@':
total_neighbours = num_neighbours(lines, line_index, index, len(lines), len(line))
if total_neighbours < 4:
total += 1
return total
def find_all_accessible_rolls(lines: []) -> int:
'''Recursively iterate through removing paper rolls and see how many are opened up for removal after each pass until none can be removed'''
total = 0
# Copy the map to note which have been removed without affecting the current checks
lines_copy = lines
for line_index, line in enumerate(lines):
for index, char in enumerate(line):
if char == '@':
total_neighbours = 0
for ii in range(max(0, line_index - 1), min(len(lines), line_index + 2)):
for jj in range(max(0, index - 1), min(len(line), index + 2)):
if ii == line_index and jj == index:
continue
if lines[ii][jj] == '@':
total_neighbours += 1
if total_neighbours < 4:
total += 1
temp_line = list(lines_copy[line_index])
temp_line[index] = '.'
lines_copy[line_index] = ''.join(temp_line)
if total != 0:
return total + find_all_accessible_rolls(lines_copy)
return total
def main():
'''Entrypoint'''
with open('input.txt', encoding='utf-8') as fh:
all_lines = fh.readlines()
part1_total = process_line(all_lines)
print(f'Part 1: {part1_total}')
part2_total = find_all_accessible_rolls(all_lines)
print(f'Part 2: {part2_total}')
if __name__ == "__main__":
main()