Prime factor of 300 000 000 000?

前端 未结 19 681
无人及你
无人及你 2021-01-03 10:23

I need to find out the prime factors of over 300 billion. I have a function that is adding to the list of them...very slowly! It has been running for about an hour now and i

相关标签:
19条回答
  • 2021-01-03 11:06

    You only need to check it's remainder mod(n) where n is a prime <= sqrt(N) where N is the number you are trying to factor. It really shouldn't take over an hour, even on a really slow computer or a TI-85.

    0 讨论(0)
  • 2021-01-03 11:09

    Just to expand/improve slightly on the "only test odd numbers that don't end in 5" suggestions...

    All primes greater than 3 are either one more or one less than a multiple of 6 (6x + 1 or 6x - 1 for integer values of x).

    0 讨论(0)
  • 2021-01-03 11:10

    The fastest algorithms are sieve algorithms, and are based on arcane areas of discrete mathematics (over my head at least), complicated to implement and test.

    The simplest algorithm for factoring is probably (as others have said) the Sieve of Eratosthenes. Things to remember about using this to factor a number N:

    • general idea: you're checking an increasing sequence of possible integer factors x to see if they evenly divide your candidate number N (in C/Java/Javascript check whether N % x == 0) in which case N is not prime.
    • you just need to go up to sqrt(N), but don't actually calculate sqrt(N): loop as long as your test factor x passes the test x*x<N
    • if you have the memory to save a bunch of previous primes, use only those as the test factors (and don't save them if prime P fails the test P*P > N_max since you'll never use them again
    • Even if you don't save the previous primes, for possible factors x just check 2 and all the odd numbers. Yes, it will take longer, but not that much longer for reasonable sized numbers. The prime-counting function and its approximations can tell you what fraction of numbers are prime; this fraction decreases very slowly. Even for 264 = approx 1.8x1019, roughly one out of every 43 numbers is prime (= one out of every 21.5 odd numbers is prime). For factors of numbers less than 264, those factors x are less than 232 where about one out of every 20 numbers is prime = one out of every 10 odd numbers is prime. So you'll have to test 10 times as many numbers, but the loop should be a bit faster and you don't have to mess around with storing all those primes.

    There are also some older and simpler sieve algorithms that a little bit more complex but still fairly understandable. See Dixon's, Shanks' and Fermat's factoring algorithms. I read an article about one of these once, can't remember which one, but they're all fairly straightforward and use algebraic properties of the differences of squares.

    If you're just testing whether a number N is prime, and you don't actually care about the factors themselves, use a probabilistic primality test. Miller-Rabin is the most standard one, I think.

    0 讨论(0)
  • 2021-01-03 11:12

    The specific number is 300425737571? It trivially factors into 131 * 151 * 673 * 22567. I don't see what all the fuss is...

    0 讨论(0)
  • 2021-01-03 11:13

    Here's some Haskell goodness for you guys :)

    primeFactors n = factor n primes
      where factor n (p:ps) | p*p > n = [n]
                            | n `mod` p /= 0 = factor n ps
                            | otherwise = p : factor (n `div` p) (p:ps)
            primes = 2 : filter ((==1) . length . primeFactors) [3,5..]
    

    Took it about .5 seconds to find them, so I'd call that a success.

    0 讨论(0)
  • 2021-01-03 11:13

    Your algorithm must be FUBAR. This only takes about 0.1s on my 1.6 GHz netbook in Python. Python isn't known for its blazing speed. It does, however, have arbitrary precision integers...

    import math
    import operator
    
    def factor(n):
        """Given the number n, to factor yield a it's prime factors.
        factor(1) yields one result: 1. Negative n is not supported."""
        M = math.sqrt(n)  # no factors larger than M
        p = 2             # candidate factor to test
        while p <= M:     # keep looking until pointless
            d, m = divmod(n, p)
            if m == 0:
                yield p   # p is a prime factor
                n = d     # divide n accordingly
                M = math.sqrt(n)  # and adjust M
            else:
                p += 1    # p didn't pan out, try the next candidate
        yield n  # whatever's left in n is a prime factor
    
    def test_factor(n):
        f = factor(n)
        n2 = reduce(operator.mul, f)
        assert n2 == n
    
    def example():
        n = 600851475143
        f = list(factor(n))
        assert reduce(operator.mul, f) == n
        print n, "=", "*".join(str(p) for p in f)
    
    example()
    
    # output:
    # 600851475143 = 71*839*1471*6857
    

    (This code seems to work in defiance of the fact that I don't know enough about number theory to fill a thimble.)

    0 讨论(0)
提交回复
热议问题