#!/usr/bin/env python # https://adventofcode.com/2025/day/7 def read_input(filename: str = "day07input.txt") -> list[list[str]]: f = open(filename, "r") lines = [l.strip("\n") for l in f.readlines()] return [list(line) for line in lines] # for part 1 we're using a top-down approach def beam1(row: int, col: int) -> int: # make sure we're inside the field assert 0 <= row <= len(field) - 1 assert 0 <= col <= len(field[0]) split_count = 0 while row < len(field): # continue down from starting position if field[row][col] == "S": row += 1 # continue down through empty space elif field[row][col] == ".": field[row][col] = "|" row += 1 # stop if we're hitting a previous beam elif field[row][col] == "|": break # split beam elif field[row][col] == "^": # print(f"splitting beam at {row=} and {col=}") split_count += 1 # left beam if col > 0: split_count += beam1(row, col - 1) # right beam if col + 1 < len(field[0]): split_count += beam1(row, col + 1) # stop current beam break else: raise Exception(f"unknown character {field[row][col]} in position {row=} and {col=}!") return split_count # solving part 2 with a bottm-up approach b/c top-down runs in O(2^n) def beam2(_field: list[list[str]]) -> int: # count the number of paths from a specific position def count_paths(r: int, c: int) -> int: # return for k in range(r+1, len(_field)): # if we encounter a splitter, return its path count if isinstance(_field[k][c], int): return _field[k][c] elif _field[k][c] == "^": raise Exception(f"I missed a splitter at row={k} and col={c}!") # if we hit the edge there is only one path return 1 # loop over all rows that can contain splitters for row in range(len(_field) - 2, 0, -2): # loop over columns in row for col in range(len(_field[row])): # if we encounter a splitter, replace it with the number of existing paths starting at its position if _field[row][col] == "^": field[row][col] = count_paths(row, col - 1) + count_paths(row, col + 1) # print final field for line in _field: print("".join([str(c) for c in line])) # return the first splitter's path count for c in _field[2]: if isinstance(c, int): return c # part 1 field = read_input() #field = read_input("testinput.txt") row, col = 0, field[0].index("S") print(beam1(row, col)) # print final field #for line in field: # print("".join(line)) # part 2 field = read_input() #field = read_input("testinput.txt") print(beam2(field))