-
Notifications
You must be signed in to change notification settings - Fork 0
/
2312.py
66 lines (63 loc) · 2.5 KB
/
2312.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
F=0
r1, r2 = 0, 0 #None
A=[]
with open('12.' + str(F)) as file:
for line in file:
line=line.strip()
L,R=line.split()
A.append([L,[int(_) for _ in R.split(',')]])
# - ???.### 1,1,3 - 1 arrangement
# - .??..??...?##. 1,1,3 - 4 arrangements
# - ?#?#?#?#?#?#?#? 1,3,1,6 - 1 arrangement
# - ????.#...#... 4,1,1 - 1 arrangement
# - ????.######..#####. 1,6,5 - 4 arrangements
# - ?###???????? 3,2,1 - 10 arrangements
from functools import lru_cache
@lru_cache(maxsize=None)
def DFS(line, resource, pt=None):
if not line or all(_ == '.' for _ in line):
if resource:
return 0 # line ends prematurely but still resources to consider
print(pt, 'validated:', line, resource)
return 1 # only valid case: IIF line is '' or '....' and no resources left
if line[0] == '?': # Wildcard: to consider both possibilities
OP = '.' + line[1:]
# '?#?' >> '##?' 1)
# >> '.#?' 2)
DM = '#' + line[1:]
# '?.#' >> '#.#' 1)
# >> '..#' 2)
return DFS(OP, resource, pt) + DFS(DM, resource, pt)
if line[0] == '#':
if not resource:
return 0 # not enough resources but still some # left
rcs = resource[0]
if len(line) < rcs: # - '###' [4]
return 0 # next resource exceeds the land we have
if not all(_ in '#?' for _ in line[:rcs]): # - '#?.#??' (3,1)
return 0 # no separator ('.') allowed in the next rcs chars
if len(resource) == 1:
return DFS(line[rcs:], resource[1:]) # mv to next even if next is nul
# case is '##.?' [2]
# will be '.?' []
if len(resource) > 1:
if len(line) < rcs + 1:
return 0 # not enough land for resources even after rcs used
if line[rcs] == '#':
return 0 # if enough land, a separator ('.') is needed
print(pt, 'move next:', line, resource)
return DFS(line[rcs + 1:], resource[1:], pt) # mv to next and next is not nul
# case is '##.?..' [2,1]
# will be '.?..' [1]
if line[0] == '.':
return DFS(line[1:], resource, pt) # mv to next validation a non-dot-filled line
for line, resource in A:
resource = tuple(resource)
r1 += DFS(line, resource, 1)
# print('part 1:', r1)
for line, resource in A:
resource = tuple(resource)
r2 += DFS(((line + "?") * 5)[:-1], resource * 5, 2)
# print('part 2:', r2)
print('part 1:', r1, '- final')
print('part 2:', r2, '- final')