2021: day07: part 2

This commit is contained in:
Antoine Martin 2021-12-07 11:04:20 +01:00
parent fa9827852d
commit e56e70a6a3

View file

@ -8,6 +8,7 @@ pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
@ -26,10 +27,44 @@ fn part1(input: &str) -> Result<u64> {
Ok(horizontal_positions
.iter()
// TODO: use abs_diff when stabilized
.map(|n| n.max(&median) - n.min(&median))
.map(|n| abs_diff(*n, median))
.sum())
}
fn part2(input: &str) -> Result<u64> {
let horizontal_positions = input
.trim()
.split(',')
.map(|n| n.parse::<u64>().context("couldn't parse position"))
.collect::<Result<Vec<_>>>()?;
let min = *horizontal_positions.iter().min().unwrap();
let max = *horizontal_positions.iter().max().unwrap();
let minimum_fuel = (min..=max)
.map(|pos| {
horizontal_positions
.iter()
.map(|n| part2_distance(*n, pos))
.sum::<f64>()
.floor() as u64
})
.min()
.unwrap();
Ok(minimum_fuel)
}
fn abs_diff(a: u64, b: u64) -> u64 {
a.max(b) - a.min(b)
}
fn part2_distance(a: u64, b: u64) -> f64 {
let distance = abs_diff(a, b) as f64;
distance * (distance + 1.0) / 2.0
}
#[cfg(test)]
mod tests {
use super::*;
@ -45,4 +80,14 @@ mod tests {
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 340056);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 168);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 96592275);
}
}