Finished PE 085, pretty quick solution with dp

This commit is contained in:
Philippe Zwietering
2023-03-14 10:03:58 +01:00
parent 0f525d4081
commit 4154392eed
3 changed files with 127 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
use std::{collections::HashMap, time::Instant};
fn _fill_dp(dp: &mut HashMap<(u32, u32), u32>, max_value: &u32) {
let mut cur_coord = (1, 1);
loop {
loop {
match cur_coord {
(1, 1) => dp.insert(cur_coord, 1),
(1, y) => dp.insert(cur_coord, dp.get(&(1, y - 1)).unwrap_or(&0) + y),
(x, 1) => dp.insert(cur_coord, dp.get(&(x - 1, 1)).unwrap_or(&0) + x),
(x, y) => dp.insert(
cur_coord,
dp.get(&(1, x)).unwrap_or(&0) * dp.get(&(y, 1)).unwrap_or(&0),
),
};
if dp.get(&cur_coord).unwrap_or(&0) > max_value {
break;
}
cur_coord.0 += 1;
}
cur_coord.0 = 1;
if dp.get(&cur_coord).unwrap_or(&0) > max_value {
break;
}
cur_coord.1 += 1;
}
}
fn fill_dp_quick(dp: &mut Vec<Vec<u32>>, max_value: &u32) -> ((usize, usize), u32) {
let mut coord = (0, 0);
let mut solution: ((usize, usize), u32) = (coord.clone(), 1);
*dp = vec![vec![1]];
loop {
loop {
match coord {
(0, 0) => {}
(x, 0) => dp.push(vec![dp[x - 1][0] + x as u32 + 1]),
(0, y) => {
let n = dp[0][y - 1] + y as u32 + 1;
dp[0].push(n);
}
(x, y) => {
let n = dp[x][0] * dp[0][y];
dp[x].push(n);
}
}
let last = dp[coord.0][coord.1];
if last.abs_diff(*max_value) < solution.1.abs_diff(*max_value) {
solution = (coord.clone(), last);
}
if last > *max_value {
break;
}
// println!("{:?} {:?}", coord, last);
coord.1 += 1;
}
coord.1 = 0;
if dp[coord.0][coord.1] > *max_value {
break;
}
coord.0 += 1;
}
solution.0 .0 += 1;
solution.0 .1 += 1;
solution
}
fn main() {
println!("Hello, this is Patrick!");
let now = Instant::now();
let max_value = 2000000;
// It is probably smarter to use memoization / keep track of intermediary solutions in order to not calculate things many many many times
// let mut solutions = HashMap::new();
// fill_dp(&mut solutions, &max_value);
// let result = solutions
// .into_iter()
// .min_by(|&(_, left), &(_, right)| left.abs_diff(max_value).cmp(&right.abs_diff(max_value)))
// .unwrap()
// .0;
let mut dp = Vec::new();
let result = fill_dp_quick(&mut dp, &max_value);
println!(
"Grid with closest to {} rectangles: {:?} * {:?} = {:?}, with {:?} rectangles",
max_value,
result.0 .0,
result.0 .1,
result.0 .0 * result.0 .1,
result.1
);
println!("Executed in {:?}", now.elapsed());
}