1
0
Fork 0
advent-of-code/2020/day13.php

60 lines
1.7 KiB
PHP
Raw Permalink Normal View History

2024-02-08 09:55:40 +01:00
<?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];
}
}