diff --git a/euler49/Cargo.toml b/euler49/Cargo.toml new file mode 100644 index 0000000..fb29373 --- /dev/null +++ b/euler49/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "euler49" +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/euler49/src/main.rs b/euler49/src/main.rs new file mode 100644 index 0000000..d0ef377 --- /dev/null +++ b/euler49/src/main.rs @@ -0,0 +1,87 @@ +use std::collections::{HashMap, HashSet}; + +type Int = i64; +const MIN_VALUE: Int = 2; +const MAX_VALUE: Int = 10_000; +const SIZE: usize = (MAX_VALUE - MIN_VALUE) as usize; +type Array = [bool; SIZE]; + +fn main() { + println!("Getting prime numbers up to {}", MAX_VALUE); + let primes = Primes::from_array(get_prime_numbers_array()); + println!("Starting to iterate ..."); + let result = find_using_iter(&primes); + for item in result { + println!("{item}"); + } +} + +fn get_prime_numbers_array() -> Array { + // Sieve of Eratosthenes + let mut result = [true; SIZE]; + for number_to_check in MIN_VALUE..(MAX_VALUE / 2) { + let mut last_number = number_to_check; + loop { + let current_number = last_number + number_to_check; + if current_number >= MAX_VALUE { + break; + } + result[(current_number - MIN_VALUE) as usize] = false; + last_number = current_number; + } + } + result +} + +struct Primes { + vector: Vec, + set: HashSet, +} +impl Primes { + fn from_array(array: Array) -> Primes { + let mut vector = Vec::new(); + let mut set = HashSet::new(); + for number in MIN_VALUE..MAX_VALUE { + if array[(number - MIN_VALUE) as usize] { + vector.push(number); + set.insert(number); + } + } + Primes { vector, set } + } +} + +fn find_using_iter(primes: &Primes) -> [Int; 3] { + for p1 in primes.vector.iter() { + let p2 = p1 + 3330; + let p3 = p2 + 3330; + if primes.set.contains(&p2) && primes.set.contains(&p3) { + let candidate = [*p1, p2, p3]; + if satisfies_checks(&candidate) { + return candidate; + } + } + } + panic!() +} + +fn satisfies_checks(cand: &[Int; 3]) -> bool { + cand.iter() + .map(|x| get_amount_of_digits(x)) + .filter(|x, y| x == y) +} + +fn get_amount_of_digits(x: Int) -> HashMap { + let mut map = get_new_map(); + x.to_string() + .chars() + .map(|c| c.to_digit(10).unwrap() as i32) + .for_each(|n| { + map.insert(n, map.get(&n).unwrap() + 1).unwrap(); + }); + map +} + +fn get_new_map() -> HashMap { + (0..=9).into_iter().zip([0; 10]).collect() +}