2

The 12th problem is :

The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...

Let us list the factors of the first seven triangle numbers:

1: 1 3: 1,3 6: 1,2,3,6 10: 1,2,5,10 15: 1,3,5,15 21: 1,3,7,21 28: 1,2,4,7,14,28 We can see that 28 is the first triangle number to have over five divisors.

What is the value of the first triangle number to have over five hundred divisors?


My program in Python 3.4

def Nfactor(n):
    k=2
    c=0
    while k<=n:
        if n%k==0:
          n=n//k
          c+=1
        else:
            k=k+1       
    return c

a=1    
for i in range(10**6):
    a+=i
    if Nfactor(a)>=500:
        print(a)
        break

I waited more than 10 minutes and never have an answer. And for my own my program is not too bad and must run in seconds.. well it makes me crazy lol i didn't find my mistake.

Can you help me please?

Thank you in advance !


EDIT

My solution now :

import math

def Nfactor(n):
    if n==1:
        return 1
    else:
        c=0

        for i in range(1, int(math.sqrt(n)+1)):
            if n%i==0:
                c+=1
        return c*2

a=0    
for i in range(1,10**6):
    a+=i
    if Nfactor(a)>=500:
        print(a)
        break
ParaH2
  • 479
  • 1
  • 4
  • 20
  • 1. I had a list of primes on hand and used those to speed up my factoring. 2. I only prime factored numbers and reconstructed factor count from the prime factorization. – NightShadeQueen Jul 21 '15 at 21:24
  • So there is (are) no mistake(s) in my code? I not i will wait so haha. I have a file with the first million of prime numbers, i will see what can i do. – ParaH2 Jul 21 '15 at 21:27
  • 3
    Number of factors != number of divisors – Eric Levieil Jul 21 '15 at 21:28
  • Your for loop has 1 million iterations (at maximum). Within each loop, you are brute forcing factors with a loop from 2 to n. That's giving the computer roughly a trillion things to do, so it's hardly surprising it takes a while. Also, this will never work, as the solution is greater than 10^6! ;) – Two-Bit Alchemist Jul 21 '15 at 21:29
  • @EricLevieil oh yeah sure ! – ParaH2 Jul 21 '15 at 21:29
  • 1
    [This might be useful](http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n). Also, memoize everything. Memoize everything. [Also, this](http://stackoverflow.com/questions/110344/algorithm-to-calculate-the-number-of-divisors-of-a-given-number) – NightShadeQueen Jul 21 '15 at 21:31
  • @NightShadeQueen I do it like him haha :) – ParaH2 Jul 21 '15 at 21:48
  • For the factors i found this one but don't know how it works def get_factors(n): return sum(2 for i in range(1, round(math.sqrt(n)+1)) if not n % i) – ParaH2 Jul 21 '15 at 22:04
  • a = 28 (the 7th triangle number) for example never happens, you should initialize `a` to 0 instead of 1 and start the `range(..)` at 1 instead of 0 – Andre Holzner Jul 21 '15 at 22:08
  • @NightShadeQueen for prime number i also use this part of code which is very nice for big numbers `from time import time from fractions import gcd tp_d=time() n=number x,y,a,c=1,1,1,1 while a==1: x=(x*x+c)%n y=(y*y+c)%n y=(y*y+c)%n a=gcd(n,abs(x-y)) ` then i return a. – ParaH2 Jul 21 '15 at 22:57

4 Answers4

3

You will most likely not get any output.

Your last value of a is 499999500001 while the smallest number for which NFactor(..) is 500, is 2^500 which is 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589376


a few hints (I have a working example which runs in less than one second now but I guess posting it here would be a spoiler):

  • as the another (deleted) answer pointed out, given the count of prime factors for a number, the number of divisors of a number is the product of (counts of each prime factor plus one), i.e. if a prime factor p appears N times, you can build N+1 products from that from 0 to p^N and combine the different powers of the primes.

  • as @NightShadeQueen points out, once you have calculated the prime factorization of a number n, keep it in a cache (I use a dict mapping from n to a dict which itself maps from a prime number to the number of times it occurs). When asked to calculate the set of prime factors for a given number, first check the cache, then start scanning from 2 upwards to see if you can find a first factor. Then call the function recursively with n divided by the first factor etc.

  • for finding prime factors of n, there is no need to go up to n, you can stop at sqrt(n)

  • when finding prime factors (k in your function Nfactor(..)), you can check k=2, k=3 (i.e. if 2 divides n, if 3 divides n etc.) and then increment k in steps of 2 (only test odd values of k after k=2)

  • as mentioned in a comment above, start with a=1 and use range(1,10**6) instead for i

Not used in my solution; found by using my favourite search engine:

  • the i'th triangle number is a = i * (i+1) / 2 so you can combine the prime factors of i and i+1 (removing one occurrence of 2). Since i and i+1 do not share any common prime factors you can even derive the number of divisors of a from the number of divisors of i and i+1.
Andre Holzner
  • 16,980
  • 6
  • 47
  • 61
  • The problem is more hard than I though... ^^ – ParaH2 Jul 21 '15 at 21:41
  • Sorry i'm french i don't understand what you mean by "you can check 2, 3 and then increment in steps of 2 (only test odd numbers)". – ParaH2 Jul 21 '15 at 22:24
  • A bit more, I don't really understand why its better to add 2 each time after divide one time by 2. PS I found the answer using an other way. :) – ParaH2 Jul 21 '15 at 22:48
3

Some thoughts...

  1. If I read correctly, you're effectively testing every number n from 2 to to n. You should be able to test just to sqrt(n). (Update: Apologies, I was not thinking clearly... it needs to be to n/2, not sqrt(n). Testing for primality would require only to sqrt(n).)
  2. Run 2 ** 500 in a python shell. I think you'll find you're not testing nearly high enough. :-)
  3. Maybe go lower... test your method with a smaller number of factors?
Andrew
  • 393
  • 2
  • 13
3

You are listing the prime numbers, but not their products. In the definition, for 28, you have 7, 14, and 28 where in your function you just count the number 7.

So the Nfactor, to do it as asked, should look like this :

def Nfactor(n):
    k=2
    c=2
    while k<n:
        if n%k == 0:
            c+=1
        k=k+1       
    return c

But there is a really faster way to get the factors (thanks to this page):

from math import sqrt
def Nfactor(n):
    factors = set()
    for x in range(1, int(sqrt(n)) + 1):
        if n % x == 0:
            factors.add(x)
            factors.add(n//x)
     return len(factors)

Also, you are not following the instructions. You don't limit your search to the numbers defined by the sum of subsequent terms (1, 1+2, 1+2+3, 1+2+3+4, etc), but are making the test for every number (for i in range(10**6):).

To have these numbers, you could use a generator (see here) like this :

def gen():
    counter = 1
    total = 0
    while True:
        total += counter
        yield total
        counter += 1

and then, you could do this to find your desired number :

g = gen()
for n in g:
    if Nfactor(n) > 500:
        print(n)
        break
BriceP
  • 508
  • 2
  • 12
0
import math
num=2
i=3
def is_notprime(num):
    j=3
    flag=int(math.sqrt(num))   
    while((j<=flag and num>=3)):    
      if num%j==0:    
        return True
        break
      else:
        j=j+2
def check_div(num):
  temp=1
  a=i
  if(num%2==0 and num>1):
    while(num%2==0):
        num=num/2
        temp+=1
  for j in range(3,int((num+5)/2),2):
    count=1
    if((is_notprime(num) and num>1) or num==j):
      while num%j==0:
        num=num/j
        count+=1
    elif num>1:
      temp=temp*2
      break

    temp=temp*count
  print("divisor is and  %d ans is %d" %(temp,a))
  return(temp)
while(i>=1):
  if(check_div(i)>5):
    break
  num+=1
  i=num*(num+1)/2