Skip to content

Commit a0c2393

Browse files
committed
2023.12.2
1 parent a0c2378 commit a0c2393

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

php/2023/12/02.php

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@
22

33
namespace Year2023\Day12;
44

5+
use common\ArrayKeyCache;
6+
7+
require_once __DIR__ . '/../../common/ArrayKeyCache.php';
8+
59
$start = microtime(true);
610

711
#$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);
1014

1115
class Arrangement {
1216

17+
private static ?ArrayKeyCache $cache = null;
18+
1319
private string $springs;
1420
private array $pattern;
1521

@@ -21,11 +27,25 @@ public function __construct(string $raw)
2127
$rawPattern = implode(",", array_fill(0, 5, $rawPattern));
2228
$this->pattern = explode(",", $rawPattern);
2329
array_walk($this->pattern, static function (&$value) {$value = (int)$value;});
30+
if (null === self::$cache) {
31+
self::$cache = new ArrayKeyCache();
32+
}
2433
}
2534

2635
public function getCountOfValidPermutations(): int
2736
{
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;
2949
}
3050

3151
private function permutateAndCount(string $springs, array $pattern): int
@@ -62,7 +82,7 @@ private function permutateAndCount(string $springs, array $pattern): int
6282
$count = 0;
6383
# if the next one is not a broken fountain - or is a wildcard - we move on with just a shorter string
6484
if ($springs[0] !== '#') {
65-
$count += $this->permutateAndCount(substr($springs, 1), $pattern);
85+
$count += $this->permutateAndCountCacheWrapper(substr($springs, 1), $pattern);
6686
}
6787

6888
# 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
7595
}
7696

7797
if ($next !== '#' && !str_contains($sub, '.')) {
78-
$count += $this->permutateAndCount(substr($springs, $nextPattern + 1), $pattern);
98+
$count += $this->permutateAndCountCacheWrapper(substr($springs, $nextPattern + 1), $pattern);
7999
}
80100

81101
return $count;

php/common/ArrayKeyCache.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace common;
4+
class ArrayKeyCache {
5+
6+
public function __construct(private readonly string $separator = ':')
7+
{}
8+
9+
private array $cache = [];
10+
11+
private function makeKey(array $key): string
12+
{
13+
return implode($this->separator, $key);
14+
}
15+
16+
public function store(array $key, $value): void
17+
{
18+
$this->cache[$this->makeKey($key)] = $value;
19+
}
20+
21+
public function retrieve(array $key): mixed
22+
{
23+
return $this->cache[$this->makeKey($key)] ?? null;
24+
}
25+
}

0 commit comments

Comments
 (0)