From 6be1a222b14dfa3067e7ab46f1b749cdbef5644a Mon Sep 17 00:00:00 2001 From: setop Date: Wed, 13 Dec 2023 14:23:41 +0100 Subject: [PATCH] day 12, part 1 faster, but not fast enough for part 2 --- d12/part1.block.py | 40 ++++++++++++++++++++++++++++++++++++++++ d12/part1.len.py | 37 +++++++++++++++++++++++++++++++++++++ d12/part1.list.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 d12/part1.block.py create mode 100644 d12/part1.len.py create mode 100644 d12/part1.list.py diff --git a/d12/part1.block.py b/d12/part1.block.py new file mode 100644 index 0000000..0d79e99 --- /dev/null +++ b/d12/part1.block.py @@ -0,0 +1,40 @@ +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) diff --git a/d12/part1.len.py b/d12/part1.len.py new file mode 100644 index 0000000..00895f5 --- /dev/null +++ b/d12/part1.len.py @@ -0,0 +1,37 @@ +import sys + +def valid(pat:str, nums:list[int]): + pat += '.' + c = 0 + for i,p in enumerate(pat): + if p == '#': + c += 1 + else: + if c>0: + if c == nums[0]: + c = 0 + nums = nums[1:] + if len(nums) == 0: + return 1 if pat[i:].find('#')<0 else 0 + else: + return 0 + return 0 + +def next(pattern, nums): + i = pattern.find('?') + if i < 0: + v = valid(pattern, nums) + if v == 1: + print("valid", pattern) + return v + else: + return next(pattern[:i]+'.'+pattern[i+1:], nums)+next(pattern[:i]+'#'+pattern[i+1:], nums) + +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) diff --git a/d12/part1.list.py b/d12/part1.list.py new file mode 100644 index 0000000..7c40b89 --- /dev/null +++ b/d12/part1.list.py @@ -0,0 +1,31 @@ +import sys + +def valid(pattern, nums): + l = [] + c = '' + for p in pattern: + if p == '#': + c+=p + else: + if len(c): + l.append(c) + c = '' + if len(c): + l.append(c) + c = '' + l = [len(m) for m in l] + return 1 if l == nums else 0 + +def next(pattern, nums): + i = pattern.find('?') + if i < 0: + return valid(pattern, nums) + else: + return next(pattern[:i]+'.'+pattern[i+1:], nums)+next(pattern[:i]+'#'+pattern[i+1:], nums) + +S= 0 +for l in sys.stdin.read().splitlines(): + pattern, snums = l.split(' ') + nums = list(map(int,snums.split(','))) + S += next(pattern, nums) +print(S)