3
3
4
4
5
5
@cache
6
- def validate (design : str , patterns : frozenset [str ]) -> bool :
7
- if design in patterns :
8
- return True
9
- else :
10
- # try all splits
11
- valid = False
12
- for i in range (1 , len (design )):
13
- if aoc .args .verbose :
14
- print (f" trying { design [:i ]} -{ design [i :]} " )
15
- valid = validate (design [:i ], patterns ) and validate (design [i :], patterns )
16
- if valid :
17
- return True
18
-
19
- return False
6
+ def validate (design : str , patterns : frozenset [str ]) -> int :
7
+ # if there's nothing left of the design after recursively slicing patterns from it,
8
+ # we found a valid arrangement. return 1 to count it in our sum of all arrangements
9
+ if not design :
10
+ return 1
11
+
12
+ # try removing all patterns from the start of the design,
13
+ # then recursively do that for each remaining segment of the design
14
+ return sum (validate (design [len (pattern ):], patterns )
15
+ for pattern in patterns if design [:len (pattern )] == pattern )
20
16
21
17
22
18
def main ():
@@ -25,19 +21,23 @@ def main():
25
21
designs = designs .splitlines ()
26
22
27
23
valid = 0
24
+ total_arrangements = 0
28
25
for design in designs :
29
- if validate (design , patterns ):
26
+ arrangements = validate (design , patterns )
27
+ if arrangements :
30
28
if aoc .args .verbose or aoc .args .progress :
31
- print (f"1 - { design } " )
29
+ print (f"1 - { design } - { arrangements } " )
32
30
valid += 1
31
+ total_arrangements += arrangements
33
32
else :
34
33
if aoc .args .verbose or aoc .args .progress :
35
34
print (f"0 - { design } " )
36
35
37
- if aoc .args .progress :
38
- print (f"cache: { validate . cache_info (). hits } hits, { validate .cache_info (). misses } misses " )
36
+ if aoc .args .verbose or aoc . args . progress :
37
+ print (f"validate() { validate .cache_info ()} " )
39
38
40
39
print (f"p1: { valid } " )
40
+ print (f"p2: { total_arrangements } " )
41
41
42
42
43
43
if __name__ == "__main__" :
0 commit comments