From 4154392eed53d7f8367bcca26cd783f855a06c40 Mon Sep 17 00:00:00 2001 From: Philippe Zwietering Date: Tue, 14 Mar 2023 10:03:58 +0100 Subject: [PATCH] Finished PE 085, pretty quick solution with dp --- projecteuler/085/Cargo.lock | 7 +++ projecteuler/085/Cargo.toml | 8 +++ projecteuler/085/src/main.rs | 112 +++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 projecteuler/085/Cargo.lock create mode 100644 projecteuler/085/Cargo.toml create mode 100644 projecteuler/085/src/main.rs diff --git a/projecteuler/085/Cargo.lock b/projecteuler/085/Cargo.lock new file mode 100644 index 0000000..88ffcd8 --- /dev/null +++ b/projecteuler/085/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "main" +version = "0.1.0" diff --git a/projecteuler/085/Cargo.toml b/projecteuler/085/Cargo.toml new file mode 100644 index 0000000..fca4e93 --- /dev/null +++ b/projecteuler/085/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "main" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projecteuler/085/src/main.rs b/projecteuler/085/src/main.rs new file mode 100644 index 0000000..7429d37 --- /dev/null +++ b/projecteuler/085/src/main.rs @@ -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>, 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()); +}