Finished PE 085, pretty quick solution with dp
This commit is contained in:
7
projecteuler/085/Cargo.lock
generated
Normal file
7
projecteuler/085/Cargo.lock
generated
Normal file
@@ -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"
|
||||
8
projecteuler/085/Cargo.toml
Normal file
8
projecteuler/085/Cargo.toml
Normal file
@@ -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]
|
||||
112
projecteuler/085/src/main.rs
Normal file
112
projecteuler/085/src/main.rs
Normal 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());
|
||||
}
|
||||
Reference in New Issue
Block a user