Created
December 14, 2020 00:42
Advent of Code 2020 Day 13
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::fs::File; | |
use std::io::{BufRead, BufReader}; | |
fn main() { | |
println!("Part 1 Solution: {}", part1()); | |
println!("Part 2 Solution: {}", part2((get_input()).1)); | |
} | |
fn get_input() -> (i64, Vec<String>) { | |
let file = File::open("input").expect("Couldn't read file"); | |
let mut input = BufReader::new(file).lines(); | |
let time_you_want_to_leave = input.nth(0).unwrap().unwrap().parse::<i64>().unwrap(); | |
let bus_schedules = input | |
.next() | |
.unwrap() // Option | |
.unwrap() // Result | |
.split(",") | |
.map(|x| x.to_string()) | |
.collect::<Vec<String>>(); | |
(time_you_want_to_leave, bus_schedules) | |
} | |
fn part1() -> i64 { | |
let (time, bus_schedules) = get_input(); | |
let best_option = bus_schedules | |
.iter() | |
.map(|x| x.parse::<i64>()) | |
.filter_map(|x| x.ok()) | |
.map(|x| (x, ((time % x) - x).abs())) | |
.min_by_key(|x| x.1) | |
.unwrap(); | |
best_option.0 * best_option.1 | |
} | |
fn part2(buses: Vec<String>) -> i64 { | |
let mut buses: Vec<(i64, i64)> = buses | |
.iter() | |
.enumerate() // Enumerate to get the # of minute offset for each bus | |
.filter(|&(_, bus)| bus != "x") | |
.map(|(index, bus)| (index as i64, bus.parse().unwrap())) | |
.collect(); | |
buses.sort_by_key(|&(_, bus)| bus); // Sorting isn't necessary, but makes it faster | |
// I initially stole this solution, but improved upon it (with for_each and better | |
// variable names).It involves Chinese Remainder Theorem and search-by-sievin, | |
let mut possible_solution = 0; | |
let mut least_common_denominator = 1; | |
buses.into_iter().for_each(|(minute_offset, bus)| { | |
while (possible_solution + minute_offset) % bus != 0 { | |
possible_solution += least_common_denominator; | |
} | |
least_common_denominator *= bus; | |
}); | |
possible_solution | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::*; | |
macro_rules! string_vec { | |
($($x:expr),*) => (vec![$($x.to_string()),*]); | |
} | |
#[test] | |
fn test_part_2() { | |
assert_eq!(part2(string_vec!["17", "x", "13", "19"]), 3417); | |
assert_eq!(part2(string_vec!["67", "7", "59", "61"]), 754018); | |
assert_eq!(part2(string_vec!["67", "x", "7", "59", "61"]), 779210); | |
assert_eq!(part2(string_vec!["67", "7", "x", "59", "61"]), 1261476); | |
assert_eq!(part2(string_vec!["1789", "37", "47", "1889"]), 1202161486); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment