class Computer extends Intcode
{
public function run()
{
while ($this->output->count() < 3 && $this->next()) {}
if ($this->stop) {
return [null, null, null];
}
$output = (array) $this->output;
$this->output = set([]);
return $output;
}
public function getInput()
{
if ($this->input->empty()) {
$this->stop = true;
return -1;
}
return $this->input->shift();
}
}
// ==================================================
// > RUN
// ==================================================
$computers = set(range(0, 49))->map(fn ($i) => (new Computer($input, [$i])));
$nat = $last_nat = [];
while (true) {
$idle = 0;
foreach ($computers as $computer) {
[$addr, $x, $y] = $computer->run();
if (is_null($addr)) {
$idle++;
continue;
}
if ($addr == 255) {
$nat = [$x, $y];
if (empty($solution_1)) $solution_1 = $nat[1];
} else {
$computers[$addr]->input = $computers[$addr]->input->merge([$x, $y]);
}
}
if ($idle >= 50 && !empty($nat)) {
if ($nat[1] === ($last_nat[1]??false)) {
$solution_2 = $nat[1];
break;
}
$computers[0]->input = $computers[0]->input->merge($nat);
$last_nat = $nat;
}
}