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);
// Part 2
let timestamp = find_incrementing(&ids);
let timestamp = find_gauss(&ids);
println!("{}", timestamp);
Ok(())
@ -28,7 +28,7 @@ fn parse_notes(input: &str) -> Result<(u32, Vec<u32>), &str> {
.next()
.ok_or("Input too short")?
.split(',')
.map(|id| id.parse().unwrap_or(0))
.map(|id| id.parse().unwrap_or(1))
.collect();
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) {
ids.iter()
.filter(|id| **id != 0)
.filter(|id| **id != 1)
.map(|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")
}
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 (largest, increment) = ids
.iter()
.enumerate()
.max_by_key(|id| id.1)
.expect("Must have at least one bus ID");
let product: u128 = ids.iter().product();
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 {
iterations += 1;
let max = increment * iterations;
if ids.iter().enumerate().rev().all(|(i, number)| {
if *number == 0 {
true
let multiplier = if m > d {
m / d + (m % d != 0) as u128
} else {
let target = max - largest as u128 + i as u128;
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
1
};
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
})
.count();
println!("{} - {}/{}", max - largest as u128, fun, ids.len());
}
}
}
.sum::<u128>()
% product
}
#[cfg(test)]
@ -124,7 +115,7 @@ mod tests {
);
let (time, ids) = parse_notes(input)?;
let timestamp = find_incrementing(&ids);
let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 3417);
@ -140,7 +131,7 @@ mod tests {
);
let (time, ids) = parse_notes(input)?;
let timestamp = find_incrementing(&ids);
let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 1068781);
@ -156,7 +147,7 @@ mod tests {
);
let (time, ids) = parse_notes(input)?;
let timestamp = find_incrementing(&ids);
let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 754018);
@ -172,7 +163,7 @@ mod tests {
);
let (time, ids) = parse_notes(input)?;
let timestamp = find_incrementing(&ids);
let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 779210);