diff --git a/day13-hard/Cargo.toml b/day13-hard/Cargo.toml new file mode 100644 index 0000000..0f3b4d9 --- /dev/null +++ b/day13-hard/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day13-hard" +version = "0.1.0" +authors = ["inga-lovinde <52715130+inga-lovinde@users.noreply.github.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day13-hard/src/main.rs b/day13-hard/src/main.rs new file mode 100644 index 0000000..b279c57 --- /dev/null +++ b/day13-hard/src/main.rs @@ -0,0 +1,64 @@ +use std::cmp::Reverse; +use std::io::{self, BufRead}; + +#[derive(Clone, Copy, Debug)] +struct Condition { + pub base: u128, + pub remainder: u128, +} + +impl Condition { + fn new(base: u128, remainder: u128) -> Condition { + Condition { + base, + remainder, + } + } +} + +impl Default for Condition { + fn default() -> Self { + Self { + base: 1, + remainder: 0, + } + } +} + +// chinese remainder theorem, sieve method +// assuming all bases are coprime +fn solve(current: Condition, remaining_conditions: &[Condition]) -> Option { + if remaining_conditions.len() == 0 { + return Some(current); + } + + let first_condition = remaining_conditions[0]; + for i in 0..first_condition.base { + if (i * current.base + current.remainder) % first_condition.base == first_condition.remainder { + return solve(Condition::new(current.base * first_condition.base, i * current.base + current.remainder), &remaining_conditions[1..]); + } + } + + return None; +} + +fn main() { + let stdin = io::stdin(); + let mut stdin_lines = stdin.lock().lines(); + let _timestamp: u128 = stdin_lines.next().unwrap().unwrap().parse().unwrap(); + let mut conditions: Vec<_> = stdin_lines.next().unwrap().unwrap().split(",") + .enumerate() + .filter(|(_index, entry)| *entry != "x") + .map(|(index, entry)| (entry.parse::().unwrap(), index)) + .map(|(base, index)| Condition::new(base, (-(index as i128)).rem_euclid(base as i128) as u128)) + .collect(); + + conditions.sort_by_key(|condition| Reverse(condition.base)); + + for condition in conditions.iter() { + println!("{:?}", condition); + } + + let solution = solve(Condition::default(), &conditions).unwrap(); + println!("{:?}", solution); +} diff --git a/day13/Cargo.toml b/day13/Cargo.toml new file mode 100644 index 0000000..5e8527a --- /dev/null +++ b/day13/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day13" +version = "0.1.0" +authors = ["inga-lovinde <52715130+inga-lovinde@users.noreply.github.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day13/src/main.rs b/day13/src/main.rs new file mode 100644 index 0000000..8c512bc --- /dev/null +++ b/day13/src/main.rs @@ -0,0 +1,23 @@ +use std::io::{self, BufRead}; + +fn get_wait_time(timestamp: u64, bus_number: u64) -> u64 { + let remainder = timestamp % bus_number; + if remainder == 0 { + return 0; + } + + bus_number - remainder +} + +fn main() { + let stdin = io::stdin(); + let mut stdin_lines = stdin.lock().lines(); + let timestamp: u64 = stdin_lines.next().unwrap().unwrap().parse().unwrap(); + let earliest_bus_number = stdin_lines.next().unwrap().unwrap().split(",") + .filter(|&entry| entry != "x") + .map(|entry| entry.parse().unwrap()) + .min_by_key(|&bus_number| get_wait_time(timestamp, bus_number)) + .unwrap(); + + println!("{}", earliest_bus_number * get_wait_time(timestamp, earliest_bus_number)); +}