function get_grid($input, $length)
{
$grid = grid("-------", 1);
$pieces = [
grid("####", 1),
grid(" # \n###\n # ")->filter(),
grid(" #\n #\n###")->filter(),
grid("#\n#\n#\n#"),
grid("##\n##")
];
$chars = $input->chars;
$bottom = 0;
for ($i = 0; $i < $length; $i++) {
$piece = $pieces[$i % 5];
$xy = xy([2, $bottom -3 - $piece->height()]);
$m = 0;
while (true) {
$m++;
if ($m % 2) {
$move = $chars->shift();
$chars[] = $move;
// Move Left or Right
if ($move == "<") {
if ($xy->x - 1 >= 0) {
$xy->move([-1, 0]);
}
} else {
if ($xy->x + $piece->width() + 1 <= 7) {
$xy->move([1, 0]);
}
}
} else {
// Move down
$move = "v";
$xy->move([0, 1]);
}
// Bottom reached
if ($xy->y + $piece->height >= $bottom) {
if ($grid->hasCollision((clone $piece)->move($xy))) {
$xy->back();
if (!($m % 2)) {
$grid->insert($xy, $piece);
$bottom = min($bottom, $xy->y);
break;
}
}
}
}
}
return $grid;
}
// ==================================================
// > PART 1 > Takes 15s
// ==================================================
// $solution_1 = get_grid($input, 2022)->rows()->keys()->min();
$solution_1 = 3200;
// ==================================================
// > PART 2 > Done manually transforming the grid and searching for a pattern
// ==================================================
function row_char($row) {
return chr(($row->keys()->reduce((fn ($id, $x) => $id + (2 ** $x)), 0)) + 92);
}
// Pattern starts at -493 : 317 stones
// Pattern ends at -3227 : 2042 stones
// => Pattern takes 1725 stones and add 2734 levels each time
// => Pattern should be repeated 579710144 times, leaving 1600 stones to check manually
// => 1584927533696 + 2551 = 1584927536247
$solution_2 = 1584927536247;