#[AllowDynamicProperties]
class Program
{
public function __construct($reg, $lines) {
$this->reg = $reg;
$this->lines = $lines;
$this->i = 0;
$this->queue = [];
$this->sent = 0;
$this->stop = false;
$this->cmds = [
"set" => fn ($p, $a, $b) => $p->reg[$a] = $p->reg[$b] ?? $b,
"add" => fn ($p, $a, $b) => $p->reg[$a] += $p->reg[$b] ?? $b,
"mul" => fn ($p, $a, $b) => $p->reg[$a] *= $p->reg[$b] ?? $b,
"mod" => fn ($p, $a, $b) => $p->reg[$a] %= $p->reg[$b] ?? $b,
"jgz" => fn ($p, $a, $b) => $p->i += ($p->reg[$a] ?? $a) > 0 ? ($p->reg[$b] ?? $b) - 1 : 0,
"snd" => fn ($p, $a) => $p->sent = $p->reg[$a] ?? $a,
"rcv" => fn ($p, $a) => $p->stop = ($p->reg[$a] ?? $a) != 0,
];
}
public function next()
{
$i_before = $this->i;
$cmd = $this->lines[$this->i];
$this->cmds[$cmd[0]]($this, $cmd[1], $cmd[2] ?? null);
$this->i++;
return $this->i != $i_before && !$this->stop && $this->i < count($this->lines);
}
}
$lines = (array) $input->lines->map(fn ($line) => explode(" ", $line->string));
$reg = array_fill_keys(array_filter(array_unique(array_column($lines, 1)), fn ($l) => in_array($l, range("a", "z"))) , 0);
$p0 = new Program($reg, $lines);
while ($p0->next());
$solution_1 = $p0->sent;
$p1 = new Program($reg, $lines);
$p2 = new Program(array_merge($reg, ["p" => 1]), $lines);
$p1->other = $p2; $p2->other = $p1;
$p1->cmds = $p2->cmds = array_merge($p1->cmds, [
"snd" => fn ($p, $a) => ++$p->sent && $p->other->queue[] = $p->reg[$a] ?? $a,
"rcv" => fn ($p, $a) => empty($p->queue) ? $p->i-- : $p->reg[$a] = array_shift($p->queue)
]);
while ($p1->next() || $p2->next());
$solution_2 = $p2->sent;