How to quickly split numbers up to 1018 into prime factors?
Answer 1, authority 100%
Well, for a guarantee – you need to check divisibility by prime numbers up to 10 ^ 9. There are about 48 million of them – not so many 🙂 So you can even try a simple search over all prime numbers, forgive the pun.
Well, and read something about integer factorization .
Update
So, taking advantage of the weekend :), I sketched a program. On my machine, using the sieve of Eratosthenes, he builds a table of primes up to 1e9 in a little less than 6 seconds, after which he factorizes numbers of the order of 9e17 in 0.23s on average; minimum – instant (microseconds), maximum – 0.45 s. Of course, I won’t say that it is fast, but … Compiled a 64-bit program.
constexpr inline unsigned long pow2 (unsigned long i) {return 1 & lt; & lt; i; }
inline unsigned long isqrt (unsigned long a)
{
unsigned long x = a;
for (unsigned long z = 0; x! = z;)
{
z = x;
x = (x + a / x) / 2;
}
return x;
}
constexpr unsigned long MAX_LIM = 1000000000; // pow2 (31) - 1;
constexpr unsigned long ARR_LIM = (MAX_LIM & gt; & gt; 6) + 1;
const unsigned long SQR_LIM = isqrt (MAX_LIM) ;;
unsigned long primes [ARR_LIM] = {0}; // 0 - simple, 1 - compound
auto set_primes = [] (unsigned long idx) {primes [idx & gt; & gt; 6] | = pow2 ((idx & amp; 0x0000003F) & gt; & gt; 1); };
auto get_primes = [] (unsigned long idx) {return primes [idx & gt; & gt; 6] & amp; pow2 ((idx & amp; 0x0000003F) & gt; & gt; 1); };
vector & lt; unsigned long & gt; Primes;
void makePrimes ()
{
for (unsigned long j = 9; j & lt; = MAX_LIM; j + = 3)
{
if (j% 2) set_primes (j);
}
for (unsigned long i = 5; i & lt; = SQR_LIM; i + = 6)
{
if (get_primes (i)) continue;
for (unsigned long j = i * i; j & lt; = MAX_LIM; j + = i)
{
if (j% 2) set_primes (j);
}
}
for (unsigned long i = 7; i & lt; = SQR_LIM; i + = 6)
{
if (get_primes (i)) continue;
for (unsigned long j = i * i; j & lt; = MAX_LIM; j + = i)
{
if (j% 2) set_primes (j);
}
}
Primes.reserve (55000000);
Primes.push_back (2);
for (unsigned long i = 3; i & lt; = MAX_LIM; i + = 2)
{
if (get_primes (i)) continue;
Primes.push_back (i);
}
}
vector & lt; unsigned long & gt; * factors (long long L, vector & lt; unsigned long & gt; * v = 0)
{
if (v == 0) v = new vector & lt; unsigned long & gt ;;
if (L == 1) return v;
for (auto f: Primes)
{
if (f * f & gt; L) {
v- & gt; push_back (L);
return v;
}
if (L% f == 0)
{
v- & gt; push_back (f);
return factors (L / f, v);
}
}
return v;
}
int main (int argc, const char * argv [])
{
makePrimes ();
printf ("Total primes =% d \ n", Primes.size ());
for (long long i = 900000000000000000ll; i & lt; 900000000000001000ll; ++ i)
{
vector & lt; unsigned long & gt; * f = factors (i);
for (auto x: * f)
{
printf ("% lu", x);
}
printf ("% lld \ n", i);
delete f;
}
}
Answer 2
my version of the partition is, in fact, the same enumeration of divisors among primes obtained by the sieve of eratosthenes.
# include & lt; iostream & gt;
#include & lt; chrono & gt;
constexpr unsigned long N = 1000000000;
bool grid [N + 2];
unsigned long primes [51000000];
unsigned long primesCount;
inline void factors (unsigned long num)
{
for (unsigned long i = 0; i & lt; primesCount; ++ i)
{
while (num% primes [i] == 0)
{
std :: cout & lt; & lt; primes [i] & lt; & lt; '';
num / = primes [i];
}
}
}
int main ()
{
auto start = std :: chrono :: high_resolution_clock :: now ();
grid [0] = grid [1] = true;
grid [2] = false;
For (unsigned long p = 3, k; p * p & lt; = n; p + = 2)
{
if (! Grid [p])
{
for (k = p * p; k & lt; = n; k + = p)
Grid [k] = True;
}
}
PRIMES [PRIMESCOUNT ++] = 2;
for (unsigned long p = 3, k; p & lt; = n; p + = 2)
{
if (! grid [p]) Primes [PRIMESCOUNT ++] = P;
}
For (unsigned long long num = 9000000000000000ll; Num & lt; 900000000000000100LL; ++ Num)
{
STD :: COUT & LT; & LT; Num & lt; & lt; "-";
FACTORS (NUM);
STD :: COUT & LT; & LT; '\ n';
}
Auto elapsedTime = STD :: Chrono :: Duration_Cast & LT;
STD :: Chrono :: MilliseConds
& gt; (STD :: Chrono :: High_Resolution_Clock :: Now () - Start);
STD :: COUT & LT; & LT; elapsedtime.count () / 1000.0f & lt; & lt; '\ n'
& lt; & lt; "PRIMES COUNT:" & lt; & lt; PRIMESCOUNT & LT; & LT; '\ n';
Return EXIT_SUCCESS;
}