From 365687ccaf7002a060fe6d2a348530a2407d31d3 Mon Sep 17 00:00:00 2001 From: Thomas Heslin <13917706+tjheslin1@users.noreply.github.com> Date: Thu, 27 Jan 2022 07:25:17 +0000 Subject: [PATCH] Complete day7: Add incrementing fuel cost calculation --- 2021/day7/src/crabmarine.rs | 91 ++++++++++++++++++++++++------------- 2021/day7/src/main.rs | 13 +++++- 2 files changed, 72 insertions(+), 32 deletions(-) diff --git a/2021/day7/src/crabmarine.rs b/2021/day7/src/crabmarine.rs index 6ff0041..b1ebc16 100644 --- a/2021/day7/src/crabmarine.rs +++ b/2021/day7/src/crabmarine.rs @@ -1,21 +1,9 @@ pub const CONSTANT_FUEL_RATE: &dyn Fn(usize, usize) -> usize = &|a: usize, b: usize| a.abs_diff(b); -pub const INCREASING_FULE_RATE: &dyn Fn(usize, usize) -> usize = &|a: usize, b: usize| { +pub const INCREASING_FUEL_RATE: &dyn Fn(usize, usize) -> usize = &|a: usize, b: usize| { let distance = a.abs_diff(b); - /* - 1 -> 1 - 2 -> 3 - 3 -> 6 - 4 -> 10 - */ - - (1..distance).fold(1, |acc, step| { - // println!("step = {}", step); - // println!("acc = {}", acc); - - acc + 1 + step - }) + (0..distance).fold(0, |acc, step| acc + 1 + step) }; pub fn calculate_cheapest_horizontal_position( @@ -33,23 +21,23 @@ pub fn calculate_cheapest_horizontal_position( .map(|s| s.parse().unwrap()) .collect::>(); - crabmarine_positions + let max_position = crabmarine_positions .iter() - .fold((0, usize::max_value()), |(acc_pos, acc_cost), crab_pos| { - // println!("Calculating fuel cost for {}", crab_pos); - - let fuel_cost = calculate_fuel_cost_for_move( - *crab_pos, - &crabmarine_positions, - fuel_cost_calculator, - ); - - if fuel_cost < acc_cost { - (*crab_pos, fuel_cost) - } else { - (acc_pos, acc_cost) - } - }) + .fold( + crabmarine_positions[0], + |acc, pos| if *pos > acc { *pos } else { acc }, + ); + + (0..max_position).fold((0, usize::max_value()), |(acc_pos, acc_cost), position| { + let fuel_cost = + calculate_fuel_cost_for_move(position, &crabmarine_positions, fuel_cost_calculator); + + if fuel_cost < acc_cost { + (position, fuel_cost) + } else { + (acc_pos, acc_cost) + } + }) } fn calculate_fuel_cost_for_move( @@ -83,12 +71,30 @@ mod tests { let input = "16,1,2,0,4,2,7,1,2,14"; let (actual_pos, actual_cost) = - calculate_cheapest_horizontal_position(input, INCREASING_FULE_RATE); + calculate_cheapest_horizontal_position(input, INCREASING_FUEL_RATE); assert_eq!(actual_pos, 5); assert_eq!(actual_cost, 168); } + #[test] + fn test_calculate_zero_fuel_cost() { + let input = vec![1]; + + let actual = calculate_fuel_cost_for_move(1, &input, CONSTANT_FUEL_RATE); + + assert_eq!(actual, 0); + } + + #[test] + fn test_calculate_zero_fuel_cost_increasing_fuel_cost() { + let input = vec![1]; + + let actual = calculate_fuel_cost_for_move(1, &input, INCREASING_FUEL_RATE); + + assert_eq!(actual, 0); + } + #[test] fn test_calculate_fuel_cost_first_position() { let input = vec![1, 5, 6, 10]; @@ -106,4 +112,27 @@ mod tests { assert_eq!(actual, 10); } + + #[test] + fn test_calculate_fuel_cost_first_position_increasing_fuel_cost() { + let input = vec![1, 5, 6, 10]; + + let actual = calculate_fuel_cost_for_move(1, &input, INCREASING_FUEL_RATE); + + let seventy = + 0 + (1 + 2 + 3 + 4) + (1 + 2 + 3 + 4 + 5) + (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9); + + assert_eq!(actual, seventy); + } + + #[test] + fn test_calculate_fuel_cost_position_increasing_fuel_cost() { + let input = vec![1, 5, 6, 10]; + + let actual = calculate_fuel_cost_for_move(4, &input, INCREASING_FUEL_RATE); + + let thirty_one = (1 + 2 + 3) + (1) + (1 + 2) + (1 + 2 + 3 + 4 + 5 + 6); + + assert_eq!(actual, thirty_one); + } } diff --git a/2021/day7/src/main.rs b/2021/day7/src/main.rs index 8a56c62..9321b5d 100644 --- a/2021/day7/src/main.rs +++ b/2021/day7/src/main.rs @@ -10,5 +10,16 @@ fn main() { let (position, cost) = crabmarine::calculate_cheapest_horizontal_position(&input, crabmarine::CONSTANT_FUEL_RATE); - println!("Optimal position = {}, with fuel cost = {}", position, cost) + println!("Optimal position = {}, with fuel cost = {}", position, cost); + + let (increasing_cost_position, increasing_cost_cost) = + crabmarine::calculate_cheapest_horizontal_position( + &input, + crabmarine::INCREASING_FUEL_RATE, + ); + + println!( + "Optimal position = {}, with increasing fuel cost = {}", + increasing_cost_position, increasing_cost_cost + ) }