Prime factor of 300 000 000 000?

前端 未结 19 678
无人及你
无人及你 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 10:49

    Finding prime factors is difficult using brute force, which sounds like the technique you are using.

    Here are a few tips to speed it up somewhat:

    • Start low, not high
    • Don't bother testing each potential factor to see whether it is prime--just test LIKELY prime numbers (odd numbers that end in 1,3,7 or 9)
    • Don't bother testing even numbers (all divisible by 2), or odds that end in 5 (all divisible by 5). Of course, don't actually skip 2 and 5!!
    • When you find a prime factor, make sure to divide it out--don't continue to use your massive original number. See my example below.
    • If you find a factor, make sure to test it AGAIN to see if it is in there multiple times. Your number could be 2x2x3x7x7x7x31 or something like that.
    • Stop when you reach >= sqrt(remaining large number)

    Edit: A simple example: You are finding the factors of 275.

    1. Test 275 for divisibility by 2. Does 275/2 = int(275/2)? No. Failed.
    2. Test 275 for divisibility by 3. Failed.
    3. Skip 4!
    4. Test 275 for divisibility by 5. YES! 275/5 = 55. So your NEW test number is now 55.
    5. Test 55 for divisibility by 5. YES! 55/5 = 11. So your NEW test number is now 11.
    6. BUT 5 > sqrt (11), so 11 is prime, and you can stop!

    So 275 = 5 * 5 * 11

    Make more sense?

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

    One last thing nobody has mentioned, perhaps because it seems obvious. Every time you find a factor and divide it out, keep trying the factor until it fails.

    64 only has one prime factor, 2. You will find that out pretty trivially if you keep dividing out the 2 until you can't anymore.

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

    Are you remembering to divide the number that you're factorizing by each factor as you find them?

    Say, for example, you find that 2 is a factor. You can add that to your list of factors, but then you divide the number that you're trying to factorise by that value.

    Now you're only searching for the factors of 150 billion. Each time around you should start from the factor you just found. So if 2 was a factor, test 2 again. If the next factor you find is 3, there's no point testing from 2 again.

    And so on...

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

    Here is an XSLT solution!

    This XSLT transformation takes 0.109 sec.

    <xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:saxon="http://saxon.sf.net/"
     xmlns:f="http://fxsl.sf.net/"
     exclude-result-prefixes="xs saxon f"
     >
     <xsl:import href="../f/func-Primes.xsl"/>
    
     <xsl:output method="text"/>
    
    
     <xsl:template name="initial" match="/*">
       <xsl:sequence select="f:maxPrimeFactor(600851475143)"/>
     </xsl:template>
    
     <xsl:function name="f:maxPrimeFactor" as="xs:integer">
       <xsl:param name="pNum" as="xs:integer"/>
    
       <xsl:sequence select=
        "if(f:isPrime($pNum))
           then $pNum
           else
             for $vEnd in xs:integer(floor(f:sqrt($pNum, 0.1E0))),
                 $vDiv1 in (2 to $vEnd)[$pNum mod . = 0][1],
                 $vDiv2 in $pNum idiv $vDiv1
               return 
                 max((f:maxPrimeFactor($vDiv1),f:maxPrimeFactor($vDiv2)))
        "/>
     </xsl:function>
    </xsl:stylesheet>
    

    This transformation produces the correct result (the maximum prime factor of 600851475143) in just 0.109 sec.:

    6857

    The transformation uses the f:sqrt() and f:isPrime() defined in FXSL 2.0 -- a library for functional programming in XSLT. FXSL is itself written entirely in XSLT.

    f:isPrime() uses Fermat's little theorem so that it is efficient to determine primeality.

    0 讨论(0)
  • 2021-01-03 11:01
    $ time factor 300000000000 > /dev/null
    
    real        0m0.027s
    user        0m0.000s
    sys         0m0.001s
    

    You're doing something wrong if it's taking an hour. You might even have an infinite loop somewhere - make sure you're not using 32-bit ints.

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

    I wouldn't expect it to take very long at all - that's not a particularly large number.

    Could you give us an example number which is causing your code difficulties?

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