Advent of code 2016/13
Ajax Direct

Answer

Part 1 :
Part 2 :
$graph = new Graph(function ($graph) {
    $pos = xy(explode(";", $graph->current));

    return $pos->getNeighbors()->mapAssoc(function ($i, $xy) use ($graph) {
        if ($xy[0] < 0 || $xy[1] < 0) return [];

        $dec = $xy[0]*$xy[0] + 3*$xy[0] + 2*$xy[0]*$xy[1] + $xy[1] + $xy[1]*$xy[1] + $graph->designer_number;
        $bin = decbin($dec);
        if (substr_count($bin, "1") % 2) return [];

        return [implode(";", $xy) => 1];
    });
});


// ==================================================
// > PART 1
// ==================================================
$graph->designer_number = $input->int;
$solution_1 = $graph->setQueue("LIFO")->explore("1;1", "31;39")[1];

// ==================================================
// > PART 2
// ==================================================
$graph->addPruning(function ($states, $graph) {
    if ($graph->values[$graph->current] >= 50) return [];

    $keep = [];

    foreach ($states as $state=>$rel) {
        if (isset($graph->values[$state]) || in_array($state, $graph->queue->queue)) continue;
        $keep[$state] = $rel;
    }

    return $keep;
});

$graph->onCompletion(function ($graph) {
    return count($graph->values);
});

$solution_2 = $graph->explore("1;1");