60 lines
1.7 KiB
PHP
60 lines
1.7 KiB
PHP
|
<?php
|
||
|
$input_file = '../inputs/day13.txt';
|
||
|
if (file_exists($input_file)) {
|
||
|
$input = file_get_contents($input_file);
|
||
|
if ($input != null) {
|
||
|
$in = array_map('trim', explode("\n", $input));
|
||
|
print 'Part 1 answer: ' . solve_part_one($in) . "\n";
|
||
|
print 'Part 2 answer: ' . solve_part_two($in) . "\n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function solve_part_one(array $in): int
|
||
|
{
|
||
|
[$arrival_time, $lines] = $in;
|
||
|
$trimmed_bus_lines = array_map('trim', explode(',', $lines));
|
||
|
$active_lines = array_filter($trimmed_bus_lines, fn ($line) => $line != 'x');
|
||
|
$bus_arrival_times = array_map(get_closest_arrival_time_to($arrival_time), $active_lines);
|
||
|
[$min_key] = array_keys($bus_arrival_times, min($bus_arrival_times));
|
||
|
return $active_lines[$min_key] * ($bus_arrival_times[$min_key] - $arrival_time);
|
||
|
}
|
||
|
|
||
|
function solve_part_two(array $in): int
|
||
|
{
|
||
|
[, $lines] = $in;
|
||
|
$trimmed_bus_lines = array_map('trim', explode(',', $lines));
|
||
|
$active_lines = array_filter($trimmed_bus_lines, fn ($line) => $line != 'x');
|
||
|
return get_first_consecutive_time($active_lines)[0];
|
||
|
}
|
||
|
|
||
|
function get_closest_arrival_time_to(int $target): callable
|
||
|
{
|
||
|
return function (int $x) use ($target): int {
|
||
|
$i = 1;
|
||
|
while ($i * $x < $target) {
|
||
|
$i += 1;
|
||
|
}
|
||
|
return $i * $x;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function get_first_consecutive_time(array $lines): array
|
||
|
{
|
||
|
if (count($lines) == 1)
|
||
|
return [0, $lines[0]];
|
||
|
else {
|
||
|
$keys = array_keys($lines);
|
||
|
$last_key = $keys[count($keys) - 1];
|
||
|
$last_elem = array_pop($lines);
|
||
|
[$previous_time, $previous_lcm] = get_first_consecutive_time($lines);
|
||
|
$timestamp = $previous_time;
|
||
|
while (true) {
|
||
|
if (($timestamp + $last_key) % $last_elem === 0)
|
||
|
break;
|
||
|
else
|
||
|
$timestamp += $previous_lcm;
|
||
|
}
|
||
|
return [$timestamp, $previous_lcm * $last_elem];
|
||
|
}
|
||
|
}
|