aoc2023/d12/part1.block.py

41 lines
1.1 KiB
Python
Raw Normal View History

import sys
def strset(s,i,c):
return s[:i]+c+s[i+1:]
def next(pat, nums, patc=''): # pat must terminiate with '.'
#print(f"next {pat=} {nums=} ({patc=}), {len(pat)+len(patc)}")
if len(nums) == 0:
if pat.find('#')<0:
#print("valid", patc)
return 1
return 0
# find all ways to build first block
l = nums[0]
block = '#'*l
rest = sum(nums[1:])
n = 0
m = len(pat)-l-rest
for i in range(m):
# if can build block:
z = pat[i:i+l].replace('?','#')
#print(f"{i=}/{m=} {z=}, {pat[i+l]}")
if z == block:
##print("march, and ", pat[i+l])
if pat[:i].find('#')<0 and not pat[i+l] == '#': # '.' or '?'
#pat = strset(pat, i+l, '.')
# recurse
r = next(pat[i+l+1:], nums[1:], patc+pat[:i].replace('?','.')+z+'.')
if r > 0:
n += r
return n
S= 0
for i,l in enumerate(sys.stdin.read().splitlines()):
pattern, snums = l.split(' ')
nums = list(map(int,snums.split(',')))
n = next(pattern+'.', nums)
print(i,l,n)
S += n
print(S)