✨ Finit le jour 16
This commit is contained in:
parent
eaa41f0afb
commit
782ed9410e
58
day_16/part_1.php
Normal file
58
day_16/part_1.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
[$instructions, $mine, $others] = explode("\n\n", file_get_contents('input.txt'));
|
||||||
|
|
||||||
|
// parse instructions
|
||||||
|
function parseInstructions($instructions)
|
||||||
|
{
|
||||||
|
// class: 1-3 or 5-7
|
||||||
|
preg_match_all('/^[a-z]+: (\d+)-(\d+) or (\d+)-(\d+)$/mi', $instructions, $matches);
|
||||||
|
if (count($matches) !== 5) {
|
||||||
|
echo sprintf('Regex failed : %s', var_export($matches, true));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$compares = [];
|
||||||
|
array_shift($matches);
|
||||||
|
for ($i = 0, $l = count($matches[0]); $i < $l; $i++) {
|
||||||
|
$compares[] = static function ($number) use ($matches, $i) {
|
||||||
|
$comparison = ($number >= (int)$matches[0][$i] and $number <= (int)$matches[1][$i])
|
||||||
|
|| ($number >= (int)$matches[2][$i] and $number <= (int)$matches[3][$i]);
|
||||||
|
if ($comparison === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return $number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return $compares;
|
||||||
|
}
|
||||||
|
|
||||||
|
$compares = parseInstructions($instructions);
|
||||||
|
|
||||||
|
// check others
|
||||||
|
$others = explode("\n", $others);
|
||||||
|
array_shift($others);
|
||||||
|
$others = array_map(static function($other) {
|
||||||
|
return explode(',', $other);
|
||||||
|
}, $others);
|
||||||
|
|
||||||
|
$sum = 0;
|
||||||
|
foreach ($others as $other) {
|
||||||
|
foreach ($other as $number) {
|
||||||
|
$is_valid = false;
|
||||||
|
foreach ($compares as $compare) {
|
||||||
|
if ($compare((int)$number) === true) {
|
||||||
|
$is_valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$is_valid) {
|
||||||
|
$sum += $number;
|
||||||
|
echo sprintf('%u not in comparison list%s', $number, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum it up
|
||||||
|
echo $sum;
|
105
day_16/part_2.php
Normal file
105
day_16/part_2.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
[$instructions, $mine, $others] = explode("\n\n", file_get_contents('input.txt'));
|
||||||
|
|
||||||
|
// parse instructions
|
||||||
|
function parseInstructions($instructions): array
|
||||||
|
{
|
||||||
|
// for example : « class: 1-3 or 5-7 »
|
||||||
|
preg_match_all('/^([a-z ]+): (\d+)-(\d+) or (\d+)-(\d+)$/mi', $instructions, $matches);
|
||||||
|
if (count($matches) !== 6) {
|
||||||
|
echo sprintf('Regex failed : %s', var_export($matches, true));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$compares = [];
|
||||||
|
array_shift($matches);
|
||||||
|
for ($i = 0, $l = count($matches[0]); $i < $l; $i++) {
|
||||||
|
$compares[$matches[0][$i]] = static function ($number) use ($matches, $i) {
|
||||||
|
$comparison = ($number >= (int)$matches[1][$i] and $number <= (int)$matches[2][$i])
|
||||||
|
|| ($number >= (int)$matches[3][$i] and $number <= (int)$matches[4][$i]);
|
||||||
|
if ($comparison === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return $number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return $compares;
|
||||||
|
}
|
||||||
|
|
||||||
|
$compares = parseInstructions($instructions);
|
||||||
|
|
||||||
|
// check valid others
|
||||||
|
$others = explode("\n", $others);
|
||||||
|
array_shift($others);
|
||||||
|
$others = array_map(static function($other) {
|
||||||
|
return explode(',', $other);
|
||||||
|
}, $others);
|
||||||
|
|
||||||
|
// filter by valid tickets
|
||||||
|
$valid_tickets = [];
|
||||||
|
foreach ($others as $other) {
|
||||||
|
$is_valid = 0;
|
||||||
|
foreach ($other as $number) {
|
||||||
|
foreach ($compares as $compare) {
|
||||||
|
if ($compare((int)$number) === true) {
|
||||||
|
$is_valid++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($is_valid === 20) {
|
||||||
|
$valid_tickets[] = $other;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter columns by what they CAN'T be
|
||||||
|
$cant_be = [];
|
||||||
|
foreach ($valid_tickets as $valid_ticket) {
|
||||||
|
foreach ($valid_ticket as $row => $number) {
|
||||||
|
foreach ($compares as $name => $compare) {
|
||||||
|
if ($compare((int)$number) !== true) {
|
||||||
|
if (
|
||||||
|
!array_key_exists($row, $cant_be) ||
|
||||||
|
(array_key_exists($row, $cant_be) && !in_array($name, $cant_be[$row], true))
|
||||||
|
) {
|
||||||
|
$cant_be[$row][] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = [];
|
||||||
|
$labels = array_keys($compares);
|
||||||
|
|
||||||
|
uasort($cant_be, static function($a, $b) {
|
||||||
|
return count($a) >= count($b) ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
// label columns
|
||||||
|
foreach ($cant_be as $row => $labels_cant_be) {
|
||||||
|
foreach ($labels as $i => $label_cant_be) {
|
||||||
|
if (!in_array($label_cant_be, $labels_cant_be, true)) {
|
||||||
|
$columns[$row] = $label_cant_be;
|
||||||
|
unset($labels[$i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($columns);
|
||||||
|
|
||||||
|
// compare to mine
|
||||||
|
$mine = explode("\n", $mine);
|
||||||
|
array_shift($mine);
|
||||||
|
$mine = explode(',', current($mine));
|
||||||
|
$departure_fields = [];
|
||||||
|
foreach ($columns as $row => $column) {
|
||||||
|
if (strpos($column, 'departure') === 0) {
|
||||||
|
$departure_fields[] = $mine[$row];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo array_product($departure_fields);
|
Loading…
Reference in New Issue
Block a user