From 6f761dea950b6cc29c15ebc7e6be8c1a6db61901 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Fri, 19 Aug 2022 12:01:23 +0200 Subject: [PATCH] finish 12 --- src/euler12/Cargo.toml | 14 +++++- src/euler12/benches/benchmark.rs | 14 ++++++ src/euler12/src/lib.rs | 82 ++++++++++++++++++++++++++++++++ src/euler12/src/main.rs | 75 ++--------------------------- 4 files changed, 114 insertions(+), 71 deletions(-) create mode 100644 src/euler12/benches/benchmark.rs create mode 100644 src/euler12/src/lib.rs diff --git a/src/euler12/Cargo.toml b/src/euler12/Cargo.toml index 3d0a76a..2be652f 100644 --- a/src/euler12/Cargo.toml +++ b/src/euler12/Cargo.toml @@ -3,10 +3,22 @@ name = "euler12" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[[bin]] +name = "euler12" +path = "src/main.rs" + +[lib] +name = "triangle" +path = "src/lib.rs" [dependencies] +criterion = "*" [profile.release] lto = true + +[[bench]] +name = "benchmark" +harness = false diff --git a/src/euler12/benches/benchmark.rs b/src/euler12/benches/benchmark.rs new file mode 100644 index 0000000..ff5feec --- /dev/null +++ b/src/euler12/benches/benchmark.rs @@ -0,0 +1,14 @@ +use criterion::{criterion_group, criterion_main, Criterion}; + +use triangle::factorize; + +fn bench_factorize(c: &mut Criterion) { + c.bench_function("factorize solution", |b| { + b.iter(|| { + factorize(76576500); + }) + }); +} + +criterion_group!(benches, bench_factorize); +criterion_main!(benches); diff --git a/src/euler12/src/lib.rs b/src/euler12/src/lib.rs new file mode 100644 index 0000000..d948a71 --- /dev/null +++ b/src/euler12/src/lib.rs @@ -0,0 +1,82 @@ +type Int = u64; + +pub fn factorize(x: Int) -> Vec { + let mut divisors = vec![]; + let limit = (x as f64).sqrt().trunc() as Int; + let numbers_to_consider = Vec::from_iter(1..=limit); + for i in numbers_to_consider { + if x % i == 0 { + divisors.push(i); + } + } + + let mut additional_divisors = vec![]; + for d in divisors.iter().skip(1) { + let number = x / d; + if !divisors.contains(&number) { + additional_divisors.push(number); + } else { + break; + } + } + additional_divisors.sort_unstable(); + divisors.append(&mut additional_divisors); + + divisors.push(x); + divisors +} + +pub struct Triangle { + last_result: Int, + last_number: Int, +} + +impl Default for Triangle { + fn default() -> Self { + Self::new() + } +} + +impl Triangle { + pub fn new() -> Self { + Triangle { + last_result: 0, + last_number: 0, + } + } +} + +impl Iterator for Triangle { + type Item = Int; + + fn next(&mut self) -> Option { + self.last_number += 1; + self.last_result += self.last_number; + Some(self.last_result) + } +} + +#[cfg(test)] +mod test { + use crate::factorize; + use crate::Triangle; + + #[test] + + fn test_factorize() { + assert_eq!(factorize(6), vec![1, 2, 3, 6]); + assert_eq!(factorize(28), vec![1, 2, 4, 7, 14, 28]); + } + + #[test] + fn test_triangle() { + let mut t = Triangle::new(); + assert_eq!(t.next().unwrap(), 1); + assert_eq!(t.next().unwrap(), 3); + assert_eq!(t.next().unwrap(), 6); + assert_eq!(t.next().unwrap(), 10); + assert_eq!(t.next().unwrap(), 15); + assert_eq!(t.next().unwrap(), 21); + assert_eq!(t.next().unwrap(), 28); + } +} diff --git a/src/euler12/src/main.rs b/src/euler12/src/main.rs index aa2a16b..1a63ab9 100644 --- a/src/euler12/src/main.rs +++ b/src/euler12/src/main.rs @@ -1,80 +1,15 @@ -use std::collections::{HashMap, HashSet}; +use triangle::{factorize, Triangle}; -type Int = u64; +const TARGET: usize = 500; fn main() { let mut triangles = Triangle::new(); - let mut factors_dict = HashMap::from([(1, vec![1])]); loop { let tn = triangles.next().unwrap(); - print!("{tn}: "); - let factors = factorize(tn, &mut factors_dict); - if factors.len() > 500 { - println!("\n{tn}"); + let factors = factorize(tn); + if factors.len() > TARGET { + println!("{tn}"); break; - } else { - println!("{}", factors.len()); } } } - -fn factorize(x: Int, dict: &mut HashMap>) -> HashSet { - let mut result = HashSet::from([x]); - let mut numbers_to_consider = HashSet::from([1..=(x / 2)]); - for i in .rev() { - if x % i == 0 { - result.insert(i); - } - } - // result.push(x); - result -} - -struct Triangle { - last_result: Int, - last_number: Int, -} - -impl Triangle { - fn new() -> Self { - Triangle { - last_result: 0, - last_number: 0, - } - } -} - -impl Iterator for Triangle { - type Item = Int; - - fn next(&mut self) -> Option { - self.last_number += 1; - self.last_result += self.last_number; - Some(self.last_result) - } -} - -#[cfg(test)] -mod test { - use crate::factorize; - use crate::Triangle; - - #[test] - - fn test_factorize() { - assert_eq!(factorize(6), vec![1, 2, 3, 6]); - assert_eq!(factorize(28), vec![1, 2, 4, 7, 14, 28]); - } - - #[test] - fn test_triangle() { - let mut t = Triangle::new(); - assert_eq!(t.next().unwrap(), 1); - assert_eq!(t.next().unwrap(), 3); - assert_eq!(t.next().unwrap(), 6); - assert_eq!(t.next().unwrap(), 10); - assert_eq!(t.next().unwrap(), 15); - assert_eq!(t.next().unwrap(), 21); - assert_eq!(t.next().unwrap(), 28); - } -}