I'm trying to solve my first ever project Euler problem just to have fun with Rust, and got stuck on what seems to be an extremely long compute time to solve
Problem: https://projecteuler.net/problem=757
I came up with this code to try to solve it, which I'm able to solve the base problem (up to 10^6) in ~245 ms and get the expected result of 2,851.
use std::time::Instant;
fn factor(num: u64) -> Vec<u64> {
let mut counter = 1;
let mut factors = Vec::with_capacity(((num as f64).log(10.0)*100.0) as _);
while counter <= (num as f64).sqrt() as _ {
let div = num / counter;
let rem = num % counter;
if rem == 0 {
factors.push(counter);
factors.push(div);
}
counter += 1
}
factors.shrink_to_fit();
factors
}
fn main() {
let now = Instant::now();
let max = 10u64.pow(6);
let mut counter = 0;
'a: for i in 1..max {
// Optimization: All numbers in the pattern appear to be evenly divisible by 4
let div4 = i / 4;
let mod4 = i % 4;
if mod4 != 0 {continue}
// Optimization: And the remainder of that divided by 3 is always 0 or 1
if div4 % 3 > 1 {continue}
let mut factors = factor(i);
if factors.len() >= 4 {
// Optimization: The later found factors seem to be the most likely to fit the pattern, so try them first
factors.reverse();
let pairs: Vec<_> = factors.chunks(2).collect();
for paira in pairs.iter() {
for pairb in pairs.iter() {
if pairb[0] + pairb[1] == paira[0] + paira[1] + 1 {
counter += 1;
continue 'a;
}
}
}
}
}
println!("{}, {} ms", counter, now.elapsed().as_millis());
}
It looks like my code is spending the most amount of time on factoring, and in my search for a more efficient factoring algorithm than what I was able to come up with on my own, I couldn't find any rust code already made (the code I did find was actually slower.) But I did a simulation to estimate how long it would take even if I had a perfect factoring algorithm, and it would take 13 days to find all numbers up to 10^14 with the non-factoring portions of this code. Probably not what the creator of this problem intends.
Given I'm relatively new to programming, is there some concept or programming method that I'm not aware of (like say using a hashmap to do fast lookups) that can be used in this situation? Or is the solution going to involve spotting patterns in the numbers and making optimizations like the ones I have found so far?