Compare commits
1 commit
45ab053ef4
...
a3b9b63181
Author | SHA1 | Date | |
---|---|---|---|
Tristan Daniël Maat | a3b9b63181 |
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue