Python
For part1, regex is king. Thought about rotating the grid for part2, but going column by column is simple enough.
view code
import re
from operator import add, mul
def part1(data: str):
# split into row, but do not split into cells yet
rows = data.splitlines()
m = len(rows) # number of rows
# initialize the result and operator arrays
# the operators array will store the operator function for each column block
# the result array will store the initial value for each column block
operators = []
res = []
# using regex to skip variable number of spaces
for symbol in re.findall(r'\S', rows[-1]):
if symbol == '+':
operators.append(add)
res.append(0)
elif symbol == '*':
operators.append(mul)
res.append(1)
n = len(res) # number of columns
# iterate through each row, except the last one
for i in range(m-1):
# use regex to find all numbers in the row
for j, num in enumerate(map(int, re.findall(r'\d+', rows[i]))):
# apply the operator to update the result for the appropriate column
res[j] = operators[j](res[j], num)
return sum(res)
def part2(data: str):
# completely split into grid
grid = [list(line) for line in data.splitlines()]
m, n = len(grid), len(grid[0])
res = 0
curr = None # current value of the block
op = None # operator for the block
for j in range(n):
if curr is None:
# we just started a new block
# update the current value and operator based on the symbol
symbol = grid[-1][j]
curr = 0 if symbol == '+' else 1
op = add if symbol == '+' else mul
# read the number from the column
num = 0
for i in range(m-1):
if grid[i][j] != ' ':
num = num * 10 + int(grid[i][j])
# if there is no number, we are at the end of a block
if num == 0:
# add the block value to the result
# and reset the current value and operator
res += curr
curr = None
op = None
continue
# otherwise, update the current value using the operator
curr = op(curr, num)
# finally, don't forget to add the last block value that's being tracked
res += curr
return res
sample = """123 328 51 64
45 64 387 23
6 98 215 314
* + * + """
assert part1(sample) == 4277556
assert part2(sample) == 3263827