#!/usr/bin/env python3 import sys, re from itertools import combinations from more_itertools import locate def memo(f): memo = {} def f2(x,y): if (x,y) not in memo: memo[(x,y)] = f(x,y) return memo[(x,y)] return f2 def fulfills(spring, cond): return [len(b) for b in spring.split('.') if len(b) > 0] == cond def solve_row1(spring, cond): if fulfills(spring, cond): return 1 sols = 0 not_dam = spring.count('?') + spring.count('#') - sum(cond) if not_dam < 1: return 0 inds = list(locate(spring, lambda x: x == '?')) for c in combinations(inds, not_dam): rs = list(spring) for i in c: rs[i] = '.' if fulfills(''.join(rs),cond): sols += 1 return sols @memo def solve_r(spring, cond): if cond == '': return 1 cond = [int(c) for c in cond.split(',')] spring = spring.strip('.') inds = list(locate(spring.strip('.'), lambda x: x == '.')) if inds == []: return solve_row1(spring, cond) i = inds[0] sols = 0 for j in range(0, len(cond)): if sum(cond[:j]) <= len(list(locate(spring[:i], lambda x: x != '.'))) and sum(cond[j:]) <= len(list(locate(spring[i:], lambda x: x != '.'))): cond1, cond2 = ','.join([str(c) for c in cond[:j]]), ','.join([str(c) for c in cond[j:]]) sols += solve_r(spring[:i], cond1) * solve_r(spring[i+1:], cond2) return sols def solve_reg(spring, cond): reg = r'^(\.|\?)*' cond = [int(c) for c in cond.split(',')] for i, z in enumerate(cond): reg += '(\?|\#){' + f'{z}' + '}' if i < (len(cond)-1): reg += '(\.|\?)+' reg += '(\.|\?)*$' print(reg, [i for i in re.findall(reg, spring, overlapped = True)]) return sum([1 for i in re.finditer(reg, spring)]) if __name__ == '__main__': springs = [line.strip('\n').split(' ') for line in open(sys.argv[1])] res1 = 0 res2 = 0 for s in springs[0:2]: # res1 += solve_row1(*s) res1 += solve_reg(*s) # print(solve_row1(*s)) # solve_reg('?'.join([s[0]] * 5), ','.join([s[1]] * 5)) print(res1, s) # challenge 1 res1 = str(res1) print(f"challenge 1:\n{res1}\n") # challenge 2 res2 = str(res2) print(f"challenge 2:\n{res2}\n")