1
Fork 0
advent-of-code/source/year_2020/day_13/mod.rs

75 lines
1.7 KiB
Rust
Raw Normal View History

2022-10-03 16:02:40 +00:00
use crate::prelude::*;
pub fn solution() -> Solution {
Solution::new(Day::new(13, 2020), part_1, part_2)
.with_expected(1895, 840493039281088_i64)
}
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())
}
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())
}