Fix performance for day 7
This commit is contained in:
Родитель
c97e04d0a1
Коммит
1582fb7249
|
@ -9,6 +9,12 @@ dependencies = [
|
|||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "array-const-fn-init"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bcb85e548c05d407fa6faff46b750ba287714ef32afc0f5e15b4641ffd6affb"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
|
@ -232,6 +238,7 @@ name = "day-7"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc-lib",
|
||||
"array-const-fn-init",
|
||||
"criterion",
|
||||
]
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
aoc-lib = { path = "../aoc-lib" }
|
||||
array-const-fn-init = "0.1.1"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
|
@ -14,3 +15,5 @@ criterion = "0.3"
|
|||
[[bench]]
|
||||
name = "bench"
|
||||
harness = false
|
||||
|
||||
[features]
|
||||
|
|
|
@ -13,38 +13,37 @@ impl AdventOfCode for Day7 {
|
|||
}
|
||||
|
||||
fn solve_1(input: &Self::Input) -> Self::Output {
|
||||
// could join into 1 loop I suppose
|
||||
let min = *input.iter().min().unwrap();
|
||||
let max = *input.iter().max().unwrap();
|
||||
// TODO: may need 2, similar to part 2?
|
||||
let median = {
|
||||
// TODO: there has to be a faster way to get the median!
|
||||
let mut sorted = input.clone();
|
||||
sorted.sort();
|
||||
sorted[sorted.len() / 2]
|
||||
};
|
||||
|
||||
(min..=max).fold(usize::MAX, |acc, i| {
|
||||
acc.min(
|
||||
input
|
||||
.iter()
|
||||
.map(|&x| ((x as isize - i as isize).abs() as usize))
|
||||
.sum(),
|
||||
)
|
||||
})
|
||||
input
|
||||
.iter()
|
||||
.map(|&x| ((x as isize - median as isize).abs() as usize))
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn solve_2(input: &Self::Input) -> Self::Output {
|
||||
// could join into 1 loop I suppose
|
||||
let min = *input.iter().min().unwrap();
|
||||
let max = *input.iter().max().unwrap();
|
||||
// take the floor and ceil of the average, and try both
|
||||
let avg1 = input.iter().sum::<usize>() / input.len();
|
||||
let avg2 = avg1 + 1;
|
||||
|
||||
(min..=max).fold(usize::MAX, |acc, i| {
|
||||
acc.min(
|
||||
input
|
||||
.iter()
|
||||
.map(|&x| calculate_fuel((x as isize - i as isize).abs() as usize))
|
||||
.sum(),
|
||||
let solutions: (usize, usize) = input.iter().fold((0usize, 0usize), |acc, &x| {
|
||||
(
|
||||
acc.0 + (calculate_fuel((x as isize - avg1 as isize).abs() as usize)),
|
||||
acc.1 + (calculate_fuel((x as isize - avg2 as isize).abs() as usize)),
|
||||
)
|
||||
})
|
||||
});
|
||||
|
||||
usize::min(solutions.0, solutions.1)
|
||||
}
|
||||
}
|
||||
|
||||
fn calculate_fuel(input: usize) -> usize {
|
||||
// seems like rust is very smart: https://godbolt.org/z/WscWfvfdr
|
||||
// TODO: figure out this algorithm and implement it myself
|
||||
(1..=input).sum()
|
||||
// calculates the triangular number
|
||||
const fn calculate_fuel(input: usize) -> usize {
|
||||
input * (input + 1) / 2
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче