Compare commits

..

1 commit

Author SHA1 Message Date
Tristan Daniël Maat a3b9b63181
Complete day 13 2020-12-14 03:53:34 +00:00

View file

@ -9,7 +9,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("{}", (arrival - time) * earliest); println!("{}", (arrival - time) * earliest);
// Part 2 // Part 2
let timestamp = find_incrementing(&ids); let timestamp = find_gauss(&ids);
println!("{}", timestamp); println!("{}", timestamp);
Ok(()) Ok(())
@ -28,7 +28,7 @@ fn parse_notes(input: &str) -> Result<(u32, Vec<u32>), &str> {
.next() .next()
.ok_or("Input too short")? .ok_or("Input too short")?
.split(',') .split(',')
.map(|id| id.parse().unwrap_or(0)) .map(|id| id.parse().unwrap_or(1))
.collect(); .collect();
Ok((estimate, ids)) Ok((estimate, ids))
@ -36,7 +36,7 @@ fn parse_notes(input: &str) -> Result<(u32, Vec<u32>), &str> {
fn find_closest_bus(time: u32, ids: &Vec<u32>) -> (u32, u32) { fn find_closest_bus(time: u32, ids: &Vec<u32>) -> (u32, u32) {
ids.iter() ids.iter()
.filter(|id| **id != 0) .filter(|id| **id != 1)
.map(|id| { .map(|id| {
let mut arrival = *id; let mut arrival = *id;
@ -50,48 +50,39 @@ fn find_closest_bus(time: u32, ids: &Vec<u32>) -> (u32, u32) {
.expect("Must have at least one bus ID") .expect("Must have at least one bus ID")
} }
fn find_incrementing(ids: &Vec<u32>) -> u128 { fn find_gauss(ids: &Vec<u32>) -> u128 {
let ids: Vec<u128> = ids.iter().map(|id| *id as u128).collect(); let ids: Vec<u128> = ids.iter().map(|id| *id as u128).collect();
let (largest, increment) = ids let product: u128 = ids.iter().product();
.iter()
.enumerate()
.max_by_key(|id| id.1)
.expect("Must have at least one bus ID");
let mut iterations = (14166999999493 - largest as u128) / increment; let gauss = |mut n: u128, mut d: u128, m: u128| -> u128 {
while d != 1 {
if m == 1 {
return 0;
};
loop { let multiplier = if m > d {
iterations += 1; m / d + (m % d != 0) as u128
let max = increment * iterations;
if ids.iter().enumerate().rev().all(|(i, number)| {
if *number == 0 {
true
} else { } else {
let target = max - largest as u128 + i as u128; 1
target % number == 0 };
}
}) {
break max - largest as u128;
} else {
if iterations % 100000000 == 0 {
let fun = ids
.iter()
.enumerate()
.filter(|(i, number)| {
if **number == 0 {
true
} else {
let target = max - largest as u128 + *i as u128;
target % **number == 0
}
})
.count();
println!("{} - {}/{}", max - largest as u128, fun, ids.len()); n = (n * multiplier) % m;
} d = (d * multiplier) % m;
} }
}
n / d
};
(0..ids.len())
.map(|a| {
let b = product / ids[a];
let bi = gauss(1, b, ids[a]);
let a = (ids[a] * a as u128 - a as u128) % ids[a] as u128;
a * b * bi
})
.sum::<u128>()
% product
} }
#[cfg(test)] #[cfg(test)]
@ -124,7 +115,7 @@ mod tests {
); );
let (time, ids) = parse_notes(input)?; let (time, ids) = parse_notes(input)?;
let timestamp = find_incrementing(&ids); let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 3417); assert_eq!(timestamp, 3417);
@ -140,7 +131,7 @@ mod tests {
); );
let (time, ids) = parse_notes(input)?; let (time, ids) = parse_notes(input)?;
let timestamp = find_incrementing(&ids); let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 1068781); assert_eq!(timestamp, 1068781);
@ -156,7 +147,7 @@ mod tests {
); );
let (time, ids) = parse_notes(input)?; let (time, ids) = parse_notes(input)?;
let timestamp = find_incrementing(&ids); let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 754018); assert_eq!(timestamp, 754018);
@ -172,7 +163,7 @@ mod tests {
); );
let (time, ids) = parse_notes(input)?; let (time, ids) = parse_notes(input)?;
let timestamp = find_incrementing(&ids); let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 779210); assert_eq!(timestamp, 779210);