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>, 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()); }