Storing vectors into memory errors when working with \(1, 2, ..., n\). e.g.
n <-600851475143for (i in n) { ... do something}
We can take a more efficient approach by only storing the sequence of odd numbers \(n\) up until \(\sqrt{n}\), i.e. the sequence \(2, 3, 5, 7, ... , \sqrt{n}\), to begin finding the factors.
We can make this even more efficient by then taking the primes of these odd number factors.
Then, we can iterate through them, by updating the next largest factor by dividing by the increasing prime factors, decreasing n incrementally until it reaches 1. This allows us to potentially find prime factors greater than \(\sqrt{n}\).
For odd \(n\), this is all that we must do. For even \(n\), we can also check repeated divisions by \(2\) until the highest odd prime factor is left.
R
Answer 1
Code
n<-600851475143primes<-c()# check odd prime factors of n up until square root of ny_primes<-c(2, seq(3, floor(sqrt(n)), 2))# find & keep only factorsy_primes<-y_primes[n%%y_primes==0]y_primes<-y_primes[primes::is_prime(y_primes)]j<-0for(iiny_primes){primes<-c(primes, i)n<-n/ij<-j+1if(primes::is_prime(n)&n>i){primes<-c(primes, n)break}}# max of this set is max primesmax(primes)# Even more impressive is jj
[1] 6857
[1] 3
Answer 2 - Even Numbers
Code
n<-600851475142factor_largest_p<-function(n){primes<-c()# for even values of n:# check repeated divisions by 2 until we find the highest odd prime factor leftif(n%%2==0){k<-1i<-nwhile((n/k)%%2==0){i<-i/2k<-k+1if(primes::is_prime(i))primes<-c(primes, i)}}# check odd prime factors of n up until square root of ny_primes<-c(2, seq(3, floor(sqrt(n)), 2))y_primes<-y_primes[n%%y_primes==0]y_primes<-y_primes[primes::is_prime(y_primes)]j<-0for(iiny_primes){primes<-c(primes, i)n<-n/ij<-j+1if(primes::is_prime(n)&n>i){primes<-c(primes, n)break}}# max of this set is max primesreturn(c(max_prime =max(primes), iter =j))}tic()factor_largest_p(600851475142)toc()