2024-01-14 21:04:10 +00:00
|
|
|
//! Day 13 of 2020.
|
|
|
|
|
2022-10-03 16:02:40 +00:00
|
|
|
use crate::prelude::*;
|
|
|
|
|
2024-01-14 21:04:10 +00:00
|
|
|
/// Get the solution for day 13 of 2020.
|
2022-10-03 16:02:40 +00:00
|
|
|
pub fn solution() -> Solution {
|
|
|
|
Solution::new(Day::new(13, 2020), part_1, part_2)
|
|
|
|
.with_expected(1895, 840493039281088_i64)
|
|
|
|
}
|
|
|
|
|
2024-01-14 21:04:10 +00:00
|
|
|
/// The logic to solve part one.
|
2022-10-03 16:02:40 +00:00
|
|
|
fn part_1(input: &str) -> Result<String> {
|
|
|
|
let mut lines = input.lines();
|
|
|
|
|
|
|
|
let target = lines.next().map(str::parse::<i32>).unwrap().unwrap();
|
|
|
|
let busses = lines
|
|
|
|
.next()
|
|
|
|
.unwrap()
|
|
|
|
.split(',')
|
|
|
|
.filter_map(|value| value.parse().ok())
|
|
|
|
.collect::<Vec<i32>>();
|
|
|
|
|
|
|
|
let mut difference = 0;
|
|
|
|
let mut earliest_bus = 0;
|
|
|
|
let mut minutes = 0;
|
|
|
|
|
|
|
|
for bus in busses {
|
|
|
|
let rest = target % bus;
|
|
|
|
|
|
|
|
if minutes < rest {
|
|
|
|
difference = bus - rest;
|
|
|
|
earliest_bus = bus;
|
|
|
|
minutes = rest;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok((earliest_bus * difference).to_string())
|
|
|
|
}
|
|
|
|
|
2024-01-14 21:04:10 +00:00
|
|
|
/// The logic to solve part two.
|
2022-10-03 16:02:40 +00:00
|
|
|
fn part_2(input: &str) -> Result<String> {
|
|
|
|
// Skip the first line, as it isn't used for the second part of the puzzle.
|
|
|
|
let input = input.lines().nth(1).unwrap();
|
|
|
|
|
|
|
|
let busses = input
|
|
|
|
.split(',')
|
|
|
|
.enumerate()
|
|
|
|
.filter_map(|(offset, bus)| {
|
|
|
|
if let Ok(bus) = bus.parse() {
|
|
|
|
Some((offset, bus))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect::<Vec<(usize, usize)>>();
|
|
|
|
|
|
|
|
let mut timestamp = 0;
|
|
|
|
// Start the increment at 1 as we'll be multiplying it with the bus numbers.
|
|
|
|
let mut increment = 1;
|
|
|
|
// Keep track of which busses we've gotten modulo equals 0 from.
|
|
|
|
let mut used_busses = vec![];
|
|
|
|
|
|
|
|
'outer: loop {
|
|
|
|
timestamp += increment;
|
|
|
|
|
|
|
|
for (offset, bus) in &busses {
|
|
|
|
if (timestamp + offset) % bus != 0 {
|
|
|
|
continue 'outer;
|
|
|
|
} else if !used_busses.contains(&(offset, bus)) {
|
|
|
|
used_busses.push((offset, bus));
|
|
|
|
increment *= bus;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break 'outer;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(timestamp.to_string())
|
|
|
|
}
|