Problem 73 : Counting fractions in a range
Consider the fraction, n/d, where n and d are positive integers. If n<d and HCF(n,d)=1, it is called a reduced proper fraction.
If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:
1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
It can be seen that there are 3 fractions between 1/3 and 1/2.
How many fractions lie between 1/3 and 1/2 in the sorted set of reduced proper fractions for d ≤ 12,000?
欧拉项目第73道题 : 1. 计数一个区间的分数
考虑分数n/d,分子n 和 分母d 是正整数。 如果 n<d且n与d互质(n和d的最大公约数是1),分数n/d被叫做最简真分数。
如果我们按分数的大小的升序列出 d ≤ 8 的最简真分数的集合,则得到
1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
可以看出,在1/3和1/2之间有3个分数。
当d ≤ 12,000时,在排序的最简真分数的集合里,位于1/3和1/2之间的分数有多少?
2. 求解分析
分数n/d是最简真分数(n < d 和HCF(n, d) = 1),还有 n/d > 1/3 且 n/d < 1/2,那么n > d/3 且 n < d/2,常规方法很容易求解的。
3. C++ 代码实现
C++采用了求解分析的思路,统计了位于1/3和1/2之间的最简真分数的个数。
C++ 代码
#include <iostream>
#include <cassert>
#include <ctime>
using namespace std;
class PE0073
{
private:
int HCF(int a, int b)
{
int tmp;
while (b != 0)
{
tmp = a;
a = b;
b = tmp % b;
}
return a;
}
public:
int findReducedProperFractions(int max_d);
};
int PE0073::findReducedProperFractions(int max_d)
{
int numOfFractions = 0;
for(int d=2; d<=max_d; d++)
{
for(int n=d/3; n<=d/2; n++)// n < d
{
// n/d > 1/3 and n/d < 1/2 and HCF(n, d) == 1
if ((d > 2*n) && (d < 3*n) && (1 == HCF(n, d)))
{
numOfFractions ++;
}
}
}
return numOfFractions;
}
int main()
{
clock_t start = clock();
PE0073 pe0073;
assert(3 == pe0073.findReducedProperFractions(8));
int max_d = 12000;
cout << "For d <= "<<max_d<<", "<< pe0073.findReducedProperFractions(max_d)<<" fractions";
cout << " lie between 1/3 and 1/2 in the sorted set of reduced proper fractions."<<endl;
clock_t finish = clock();
double duration=(double)(finish - start) / CLOCKS_PER_SEC;
cout << "C/C++ running time: " << duration << " seconds" << endl;
return 0;
}
4. Python 代码实现
Python和C++一样,采用了求解分析的思路,统计了位于1/3和1/2之间的最简真分数的个数, 但运行时间相比C++太多了。
肯定还有其他更好的求解方法。
Python
import time
def HCF(a, b):
while b != 0:
(a, b) = (b, a % b)
return a
def findReducedProperFractions(max_d):
numOfFractions = 0
for d in range(2, max_d+1):
for n in range(d//3, d//2+1): # n > d/3 and n < d/2
if (d > 2*n) and (d < 3*n) and (1 == HCF(n, d)):
numOfFractions += 1
return numOfFractions
def main():
start = time.process_time()
assert 3 == findReducedProperFractions(8)
max_d = 12000
total = findReducedProperFractions(max_d)
print("For d <= %d , %d" %(max_d, total), "fractions lie between", end=' ')
print("1/3 and 1/2 in the sorted set of reduced proper fractions")
end = time.process_time()
print('PE0073 spent CPU processing time :', end-start)
if __name__ == '__main__':
main()