Problem 12 : Highly divisible triangular number
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?
1. 第12个问题 : 高度可除的三角数
三角形数的序列是通过增加自然数来生成的。 因此第7个三角形数是1+2+3+4+5+6+7 = 28。 前十项是:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …
让我们列出前七个三角形数的因子:
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
我们可以看到,28是第一个有超过五个除数(或因数)的三角形数。
有超过五百个除数(因数)的第一个三角形数的值是多少?
2. 求解分析
这道题需要三个函数:第一,计算第n个三角形数,第二,找出任意数的因子的个数,第三, 找到满足需要的第一个三角形数。
3. C++ 代码实现
类PE0012有三个成员函数:
函数getTriangleNumber(int n) 计算第n个三角形数。
函数getNumOfDivisors(int number) 获得一个数有的因子个数。
函数findFirstTriangleNumber(const int numOfDivisors) 根据除数或因子的个数找到满足条件的第一个三角形数。
C++ 代码
#include <iostream>
#include <cassert>
#include <cmath>
using namespace std;
class PE0012
{
private:
int getTriangleNumber(int n);
public:
int getNumOfDivisors(int number);
int findFirstTriangleNumber(const int numOfDivisors);
};
int PE0012::getTriangleNumber(int n)
{
int num = n*(n+1)/2;
return num;
}
int PE0012::getNumOfDivisors(int number)
{
int numOfDivisors = 0;
double squareRoot = sqrt((double)number);
for(int i=1;i<=(int)squareRoot;i++)
{
if (number % i == 0)
{
numOfDivisors++;
if (i*i != number)
{
numOfDivisors++;
}
}
}
return numOfDivisors;
}
int PE0012::findFirstTriangleNumber(const int numOfDivisors)
{
int n = 7; // 7th triangle number is 28
int numOfFactors = 6; // triangle number 28 has 6 divisors
int triangleNumber;
while (numOfFactors < numOfDivisors)
{
n++;
triangleNumber = getTriangleNumber(n);
numOfFactors = getNumOfDivisors(triangleNumber);
}
return triangleNumber;
}
int main()
{
PE0012 pe0012;
assert(6 == pe0012.getNumOfDivisors(28));
cout << "The first triangle number " << pe0012.findFirstTriangleNumber(500);
cout << " has over five hundred divisors." << endl;
return 0;
}
4. Python 代码实现
Python实现方法跟C++一样。我们定义了三个函数:
- getTriangleNumber(n)
- getNumOfDivisors(number)
- getFirstTriangleNumber(numOfDivisors)
奇怪的是,虽然使用了同样实现方法,Python代码的运行速度没有C++代码的快。
Python 代码
import math
def getTriangleNumber(n):
""" computer nth triangle number: n*(n+1)/2
"""
return n*(n+1)//2
def getNumOfDivisors(number):
numOfDivisors = 0
for i in range(1, int(math.sqrt(number))+1):
if 0 == number % i:
numOfDivisors += 2
if i*i == number:
numOfDivisors -= 1
return numOfDivisors
def getFirstTriangleNumber(numOfDivisors):
n = 1
numOfFactors = 1
while(numOfFactors < numOfDivisors):
n += 1
triangleNumber = getTriangleNumber(n)
numOfFactors = getNumOfDivisors(triangleNumber)
return triangleNumber
def main():
assert 6 == getNumOfDivisors(28)
print("The first triangle number %d" % getFirstTriangleNumber(500),end='')
print(" has over five hundred divisors.")
if __name__ == '__main__':
main()