2
2
3
3
namespace Year2023 \Day12 ;
4
4
5
+ use common \ArrayKeyCache ;
6
+
7
+ require_once __DIR__ . '/../../common/ArrayKeyCache.php ' ;
8
+
5
9
$ start = microtime (true );
6
10
7
11
#$lines = file('example.txt', FILE_IGNORE_NEW_LINES);
8
- $ lines = file ('example2.txt ' , FILE_IGNORE_NEW_LINES );
9
- # $lines = file('input.txt', FILE_IGNORE_NEW_LINES);
12
+ # $lines = file('example2.txt', FILE_IGNORE_NEW_LINES);
13
+ $ lines = file ('input.txt ' , FILE_IGNORE_NEW_LINES );
10
14
11
15
class Arrangement {
12
16
17
+ private static ?ArrayKeyCache $ cache = null ;
18
+
13
19
private string $ springs ;
14
20
private array $ pattern ;
15
21
@@ -21,11 +27,25 @@ public function __construct(string $raw)
21
27
$ rawPattern = implode (", " , array_fill (0 , 5 , $ rawPattern ));
22
28
$ this ->pattern = explode (", " , $ rawPattern );
23
29
array_walk ($ this ->pattern , static function (&$ value ) {$ value = (int )$ value ;});
30
+ if (null === self ::$ cache ) {
31
+ self ::$ cache = new ArrayKeyCache ();
32
+ }
24
33
}
25
34
26
35
public function getCountOfValidPermutations (): int
27
36
{
28
- return $ this ->permutateAndCount ($ this ->springs , $ this ->pattern );
37
+ return $ this ->permutateAndCountCacheWrapper ($ this ->springs , $ this ->pattern );
38
+ }
39
+
40
+ private function permutateAndCountCacheWrapper (string $ springs , array $ pattern ): int
41
+ {
42
+ $ key = $ pattern ;
43
+ $ key [] = $ springs ;
44
+ if (null === ($ result = self ::$ cache ->retrieve ($ key ))) {
45
+ $ result = $ this ->permutateAndCount ($ springs , $ pattern );
46
+ self ::$ cache ->store ($ key , $ result );
47
+ }
48
+ return $ result ;
29
49
}
30
50
31
51
private function permutateAndCount (string $ springs , array $ pattern ): int
@@ -62,7 +82,7 @@ private function permutateAndCount(string $springs, array $pattern): int
62
82
$ count = 0 ;
63
83
# if the next one is not a broken fountain - or is a wildcard - we move on with just a shorter string
64
84
if ($ springs [0 ] !== '# ' ) {
65
- $ count += $ this ->permutateAndCount (substr ($ springs , 1 ), $ pattern );
85
+ $ count += $ this ->permutateAndCountCacheWrapper (substr ($ springs , 1 ), $ pattern );
66
86
}
67
87
68
88
# if there is a block exactly the size of the next pattern that does not contain a separator, we recurse on
@@ -75,7 +95,7 @@ private function permutateAndCount(string $springs, array $pattern): int
75
95
}
76
96
77
97
if ($ next !== '# ' && !str_contains ($ sub , '. ' )) {
78
- $ count += $ this ->permutateAndCount (substr ($ springs , $ nextPattern + 1 ), $ pattern );
98
+ $ count += $ this ->permutateAndCountCacheWrapper (substr ($ springs , $ nextPattern + 1 ), $ pattern );
79
99
}
80
100
81
101
return $ count ;
0 commit comments