day 12, part 1 faster, but not fast enough for part 2
This commit is contained in:
		
							
								
								
									
										40
									
								
								d12/part1.block.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								d12/part1.block.py
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
							
								
								
									
										37
									
								
								d12/part1.len.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								d12/part1.len.py
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
							
								
								
									
										31
									
								
								d12/part1.list.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								d12/part1.list.py
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user