You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.2 KiB
81 lines
2.2 KiB
#!/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")
|
|
|
|
|