Advent of code 2016/25
Ajax Direct

Answer 1870ms

Part 1 : 192 Part 2 :
function solve($input, $r) {
    $out = "";
    $j   = 0;

    for ($i = 0; $i < $input->lines->count(); $i++) {
        $c = explode(" ", $input->lines[$i]->string);

        // Break as soon as pattern is invalid
        $pattern = substr($out, 0, -(strlen($out) % 2));
        if ($pattern && !preg_match("/^(?:01)+$/", $pattern)) return false;

        // If we reach 100k iteration without breaking the pattern, we have a valid pattern
        if ($j++ > 100_000) return true;

        switch ($c[0]) {
            case "cpy":
                if (!is_string($c[2])) break;
                $r[$c[2]] = $r[$c[1]] ?? $c[1]; break;
            case "inc":
                $r[$c[1]]++; break;
            case "dec":
                $r[$c[1]]--; break;
            case "jnz":
                if ($r[$c[1]] ?? $c[1]) $i += ($r[$c[2]] ?? $c[2]) - 1; break;
            case "out":
                $out .= $r[$c[1]] ?? $c[1];
                break;
        }
    }
}

// ==================================================
// > SOLUTIONS
// ==================================================
$r = array_fill_keys(["a", "b", "c", "d"], 0);

for ($solution_1 = 0;; $solution_1++) {
    $r["a"] = $solution_1;
    if (solve($input, $r)) break;
}

$solution_2 = "⭐";