$dir = [
"w" => [-1, 0],
"e" => [ 1, 0],
"nw" => [-1, -1],
"ne" => [ 0, -1],
"sw" => [ 0, 1],
"se" => [ 1, 1],
];
// ==================================================
// > PART 1
// ==================================================
$grid = grid();
foreach ($input->lines as $line) {
$xy = xy([0, 0]);
foreach ($line->matchAll("/w|e|nw|ne|sw|se/")[0] as $d) {
$xy->move($dir[(string) $d]);
}
$grid->set($xy, !$grid->get($xy));
}
$solution_1 = $grid->cells()->filter()->count();
// ==================================================
// > PART 2
// ==================================================
$g = (array) $grid->rows->map(fn ($r) => (array) $r->filter());
for ($i = 0; $i < 100; $i++) {
$g2 = [];
foreach (array_keys($g) as $y) foreach (array_keys($g[$y]) as $x) {
$nei = [];
foreach ($dir as [$dx, $dy]) $nei[] = [$x + $dx, $y + $dy];
foreach ($nei as [$nx, $ny]) {
if (isset($g2[$ny][$nx])) continue;
$count = 0;
foreach ($dir as [$dx, $dy]) {
if (!empty($g[$ny + $dy][$nx + $dx])) $count++;
};
$cell = $g[$ny][$nx] ?? false;
if ($cell && (!$count || $count > 2)) $cell = false;
if (!$cell && $count == 2) $cell = true;
$g2[$ny][$nx] = $cell;
}
}
$g = array_map("array_filter", $g2);
}
$solution_2 = set($g)->merge()->count();