preg_match("/initial state: ([^\n]+)/", $input, $state);
$state = str_repeat(".", 150) . $state[1] . str_repeat(".", 150);
preg_match_all("/([\.#]{5}) => #/", $input, $comb);
$comb = array_fill_keys($comb[1], "#");
function grow($state, $comb) {
$next = "";
for ($i = 0; $i < strlen($state); $i++) {
$next[$i] = $comb[implode("", [
$state[$i - 2] ?? ".",
$state[$i - 1] ?? ".",
$state[$i] ?? ".",
$state[$i + 1] ?? ".",
$state[$i + 2] ?? "."
])] ?? ".";
}
return $next;
}
$p = [];
$d = [];
for ($i = 0; $i < 150; $i++) {
$state = grow($state, $comb);
$plants = set(str_split($state))->keep("#");
$p[$i] = $plants->keys()->sum() - $plants->count() * 150;
$d[$i] = $p[$i] - ($p[$i - 1]??0);
}
// ==================================================
// > PART 1
// ==================================================
$solution_1 = $p[19];
// ==================================================
// > PART 2
// ==================================================
$incr = $d[149]; // Last diff is the repeated increment
$start = array_search($incr, $d); // Start of the repeated increment in the loop
$solution_2 = $p[$start] + (50_000_000_000 - $start - 1) * $incr; // Calc increments left after we enter the loop until 5B iterations