✨ Finit le jour 4
This commit is contained in:
parent
10b3cd3730
commit
eee724e103
119
day_4/part_2.php
Normal file
119
day_4/part_2.php
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
// prepare numbers and grids
|
||||
$parts = explode("\n\n", file_get_contents('./input.txt'));
|
||||
|
||||
$numbers = array_map('intval', explode(',', array_shift($parts)));
|
||||
|
||||
$grids = array_map(static function($part) { return explode("\n", $part); }, $parts);
|
||||
|
||||
array_walk_recursive($grids, static function (&$grid) {
|
||||
if (is_string($grid)) {
|
||||
$grid = array_map(static function($g) {
|
||||
return 0;
|
||||
}, array_flip(array_map('trim', str_split($grid, 3))));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Marks cell as done
|
||||
*
|
||||
* @param array $grids
|
||||
* @param int $number
|
||||
*/
|
||||
function modify_grids(array &$grids, int $number)
|
||||
{
|
||||
foreach ($grids as $i_grid => $grid) {
|
||||
foreach ($grid as $i_row => $row) {
|
||||
foreach ($row as $cell => $cell_val) {
|
||||
if ($cell === $number) {
|
||||
$grids[$i_grid][$i_row][$cell] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List all unmarked cell from a grid
|
||||
*
|
||||
* @param array $grid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_unmarked_from(array $grid): array
|
||||
{
|
||||
$unmarked = [];
|
||||
foreach ($grid as $row) {
|
||||
$unmarked = array_merge($unmarked, array_keys(array_filter($row, static function($cell) {
|
||||
return $cell === 0;
|
||||
})));
|
||||
}
|
||||
return $unmarked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a grid is winning
|
||||
*
|
||||
* @param array $grids
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
function check_grids(array &$grids): bool|array
|
||||
{
|
||||
$result = false;
|
||||
|
||||
foreach ($grids as $i => $grid) {
|
||||
if (check_lines($grid)) {
|
||||
if (count($grids) === 1) return $grid;
|
||||
unset($grids[$i]);
|
||||
$result = true;
|
||||
}
|
||||
$rotated_grid = [];
|
||||
$i = 0;
|
||||
while (!empty($grid)) {
|
||||
foreach ($grid as $j => $row) {
|
||||
$rotated_grid[$i][array_key_last($row)] = array_pop($row);
|
||||
$grid[$j] = $row;
|
||||
if (empty($row)) unset($grid[$j]);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if (check_lines($rotated_grid)) {
|
||||
if (count($rotated_grid) === 1) return $grid;
|
||||
unset($grids[$i]);
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a line is all done
|
||||
*
|
||||
* @param array $grid
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
function check_lines(array $grid): bool|array
|
||||
{
|
||||
foreach ($grid as $row) {
|
||||
if (array_sum($row) === 5) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($numbers as $number) {
|
||||
modify_grids($grids, (int)$number);
|
||||
$count = count($grids);
|
||||
$test = check_grids($grids);
|
||||
if ($count === 1 && $test) {
|
||||
$grid = get_unmarked_from(is_array($test) ? $test : current($grids));
|
||||
echo array_sum($grid) * $number;
|
||||
break;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user