113 lines
2.9 KiB
Rust
113 lines
2.9 KiB
Rust
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());
|
|
}
|