Project Euler problem 33要求求解器找到“奇怪的分数”:分数等于通过删除出现在分子和分母中的数字得到的分数(例如,49/98,“取消”到4 / 8删除9s)。
注意:这不是解决Project Euler问题最快的竞争。我已经将这段代码改写成了与Nickie一样快的解决方案。这是通过删除for循环和浮动(数字)...条件来完成的。它看起来像这样:
def curious(numer,denom):
n = str(numer)
d = str(denom)
if len(n) == 2 and len(d) == 2:
if n[1] == d[0]:
if n != d:
if d[1] != "0":
if Fraction(int(n[0]), int(d[1])) \
== \
Fraction(numer, denom):
return n + d
我仍然不明白条件问题。
我不是Python编程的新手,这是我第一次遇到这样的事情。在下面定义的函数中,有成对的if和elif语句:
import time
from fractions import Fraction
def curious(numer,denom):
n = str(numer)
d = str(denom)
if len(n) == 2 and len(d) == 2:
if n[1] == d[0]:
for i in range(2, numer+1):
if float(numer)/i == float(int(n[0])) \
and float(denom)/i == float(int(d[1])):
if n != d:
return n + "/" + d
elif d[1] != "0":
if Fraction(int(n[0]), int(d[1])) \
== \
Fraction(numer, denom):
if n != d:
return n + d
start = time.time()
nums = []
denoms = []
for i in range(10, 100):
for j in range(10, 100):
if i < j:
if type(curious(i, j)) == str:
frac = (curious(i,j))
nums.append(frac[0]+frac[1])
denoms.append(frac[2]+frac[3])
print frac
pro = 1
duct = 1
for i in range(0, len(nums)):
pro *= int(nums[i])
duct *= int(denoms[i])
print Fraction(pro, duct)
elapsed = time.time() - start
print "The elapsed time is %s seconds." % (elapsed)
当我运行带有elif语句注释掉的代码时,结果如下:
16/64,
19/95,
26/65,
The elapsed time is 0.0500001907349 seconds.
但是当包含elif时,if语句将被忽略,结果如下:
1664,
1995,
2665,
4998,
The elapsed time is 0.59700012207 seconds.
似乎Python更喜欢采用低效路由,即使在两种情况下都满足if语句的条件。任何人都可以帮我解开这个谜团吗?
理想情况下,我希望结果为:
16/64,
19/95,
26/65,
4998,
The elapsed time is 0.0500001907349 seconds.
答案 0 :(得分:4)
这是一个奇怪的结构化答案,因为它是逐步编写的。我为此道歉。即便如此,我认为值得按此顺序阅读。每个部分用水平标尺分开,表示不同的东西。
浮点算术中的等式比较是常见的麻烦来源,应该避免。而不是测试:
float(numer)/i == float(int(n[0])) and float(denom)/i == float(int(d[1]))
为什么不以下?更简单和等效(在数学中,但不在Python中!):
numer == i * int(n[0]) and denom == i * int(d[1])
除此之外,浮点运算不仅会成为问题的根源,而且从int
到float
的转换也往往对性能不利。
我不明白为什么您希望程序在删除elif
子句时打印相同的结果。它有两个不同的东西,当你有elif
时,当你没有if
时。你只是返回相同的结果(n / d),所以你没有看到差异。
for
语句不是“被绕过”。但是,如果它在elif
循环的第一次迭代中没有返回某些内容,那么if
语句(在每次迭代中执行相同的操作)将有机会返回其值。然后curious
语句将不会再次执行。
现在提供了有关该问题的更多信息(这是作为Euler project's problem #33解决方案的一部分),我将坚持问题的原始版本并尝试重构函数for
我相信写得不好。我相信以下函数是等效的,速度更快,因为i
循环只计算依赖于def curious(numer,denom):
n = str(numer)
d = str(denom)
if len(n) == 2 == len(d) and n[1] == d[0] and n != d:
for i in range(2, numer+1):
if numer == i*int(n[0]) and denom == i*int(d[1]):
return n + "/" + d
elif i == 2 and d[1] != "0":
if Fraction(int(n[0]), int(d[1])) == Fraction(numer, denom):
return n + d
的东西:
curious
使用此功能,Cawb07的程序产生相同的输出(四个分数加1/100,这是问题的答案)要快得多。
既然我明白curious
正在尝试做什么,那么让我建议一个更好的方法。让我们假设要寻求蛮力解决方案。它可以很容易地安排,以便始终使用两个2位数参数调用numer < denom
,for
为真,并返回布尔结果,表示该分数是否好奇。此外,curious
中不需要import time
from fractions import Fraction
def curious(numer, denom):
n = str(numer)
d = str(denom)
return (n[0] == d[1] != '0' and denom * int(n[1]) == numer * int(d[0])) \
or (n[0] == d[0] != '0' and denom * int(n[1]) == numer * int(d[1])) \
or (n[1] == d[0] != '0' and denom * int(n[0]) == numer * int(d[1])) \
or (n[1] == d[1] != '0' and denom * int(n[0]) == numer * int(d[0]))
start = time.time()
for i in range(10, 100):
for j in range(i+1, 100):
if curious(i, j):
print i, "/", j
elapsed = time.time() - start
print "The elapsed time is", elapsed, "seconds."
循环,这可以大大简化。
fractions.gcd(n,d)
这个程序只打印出四个好奇的部分,再次比前一部分快得多。
另请注意,为了将好奇分数的乘积减少到最低常用项,您可以轻松计算分母和分母,然后除以它们的GCD,可以使用Euclid's algorithm找到。
Cawb07:也可以使用{{1}}:)。
答案 1 :(得分:2)
在我的以下代码中,根据 ELIF 的值,elif section
处于有效或停用状态。
import time
from fractions import Fraction
def curious(numer,denom,disp=None):
n = str(numer)
d = str(denom)
fracs = []
if n!=d and n[1] == d[0]:
ELIF = 1
fn0 = float(n[0])
fd1 = float(d[1])
if disp:
print ('---------------------------------------\n'
'n == %s d == %s\n'
"float('%s'[0]) == %f float('%s'[1]) == %f"
% ( n,d,n,fn0,d,fd1 ) )
for i in range(2, numer+1):
if disp:
print ('i== %2d '
'%s./%2d==%10f %s./%2d==%10f %s' %
(i,n,i,float(n)/i,d,i,float(d)/i,
float(n)/i==fn0 and float(d)/i==fd1) )
if float(numer)/i==fn0 and float(denom)/i==fd1:
if disp:
print (' %s\n'
' - %s/%s returned by if section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n,d))
return n + "/" + d
elif ELIF and d[1] != "0":
if Fraction( n[0] + '/' + d[1] ) \
== \
Fraction(numer, denom):
if disp:
print (' %s\n'
" Fraction('%s/%s') == %s\n"
" Fraction(%s, %s) == %s\n"
' - %s%s returned by elif section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n[0],d[1],Fraction( n[0] + '/' + d[1] ),
numer,denom,Fraction(numer, denom),n,d) )
return n + d
else:
if n+d=='4998':
if disp:
print (' - elif part is active -' if ELIF
else ' - elif part is not active -')
print ' - No convenient divisor found for 49 98 : returned by else section -'
return 'No convenient divisor found for 49 98'
start = time.time()
nums,denoms = [],[]
fracs = []
for i in range(10, 100):
for j in range(10, 100):
if curious(i,j):
frac = (curious(i,j,'display'))
print('frac == %s' % frac)
fracs.append(frac)
deb,end = frac[0:2],frac[-2:]
try:
int(deb)
nums.append(deb)
denoms.append(end)
except:
print "can't record %r==frac[0:2] as numerator" % (deb,)
print '\ndetected :\n %s' % '\n '.join(fracs)
pro,duct = 1,1
print '\nnums ==',nums
print 'denoms ==',denoms
for i in range(0, len(nums)):
pro *= int(nums[i])
duct *= int(denoms[i])
print 'pro,duct ==',pro,duct
print 'Fraction(pro, duct) ==',Fraction(pro, duct)
elapsed = time.time() - start
print "The elapsed time is %s seconds." % (elapsed)
ELIF = 0
---------------------------------------
n == 16 d == 64
float('16'[0]) == 1.000000 float('64'[1]) == 4.000000
i== 2 16./ 2== 8.000000 64./ 2== 32.000000 False
i== 3 16./ 3== 5.333333 64./ 3== 21.333333 False
i== 4 16./ 4== 4.000000 64./ 4== 16.000000 False
i== 5 16./ 5== 3.200000 64./ 5== 12.800000 False
i== 6 16./ 6== 2.666667 64./ 6== 10.666667 False
i== 7 16./ 7== 2.285714 64./ 7== 9.142857 False
i== 8 16./ 8== 2.000000 64./ 8== 8.000000 False
i== 9 16./ 9== 1.777778 64./ 9== 7.111111 False
i== 10 16./10== 1.600000 64./10== 6.400000 False
i== 11 16./11== 1.454545 64./11== 5.818182 False
i== 12 16./12== 1.333333 64./12== 5.333333 False
i== 13 16./13== 1.230769 64./13== 4.923077 False
i== 14 16./14== 1.142857 64./14== 4.571429 False
i== 15 16./15== 1.066667 64./15== 4.266667 False
i== 16 16./16== 1.000000 64./16== 4.000000 True
- elif part is not active -
- 16/64 returned by if section -
frac == 16/64
---------------------------------------
n == 19 d == 95
float('19'[0]) == 1.000000 float('95'[1]) == 5.000000
i== 2 19./ 2== 9.500000 95./ 2== 47.500000 False
i== 3 19./ 3== 6.333333 95./ 3== 31.666667 False
i== 4 19./ 4== 4.750000 95./ 4== 23.750000 False
i== 5 19./ 5== 3.800000 95./ 5== 19.000000 False
i== 6 19./ 6== 3.166667 95./ 6== 15.833333 False
i== 7 19./ 7== 2.714286 95./ 7== 13.571429 False
i== 8 19./ 8== 2.375000 95./ 8== 11.875000 False
i== 9 19./ 9== 2.111111 95./ 9== 10.555556 False
i== 10 19./10== 1.900000 95./10== 9.500000 False
i== 11 19./11== 1.727273 95./11== 8.636364 False
i== 12 19./12== 1.583333 95./12== 7.916667 False
i== 13 19./13== 1.461538 95./13== 7.307692 False
i== 14 19./14== 1.357143 95./14== 6.785714 False
i== 15 19./15== 1.266667 95./15== 6.333333 False
i== 16 19./16== 1.187500 95./16== 5.937500 False
i== 17 19./17== 1.117647 95./17== 5.588235 False
i== 18 19./18== 1.055556 95./18== 5.277778 False
i== 19 19./19== 1.000000 95./19== 5.000000 True
- elif part is not active -
- 19/95 returned by if section -
frac == 19/95
---------------------------------------
n == 26 d == 65
float('26'[0]) == 2.000000 float('65'[1]) == 5.000000
i== 2 26./ 2== 13.000000 65./ 2== 32.500000 False
i== 3 26./ 3== 8.666667 65./ 3== 21.666667 False
i== 4 26./ 4== 6.500000 65./ 4== 16.250000 False
i== 5 26./ 5== 5.200000 65./ 5== 13.000000 False
i== 6 26./ 6== 4.333333 65./ 6== 10.833333 False
i== 7 26./ 7== 3.714286 65./ 7== 9.285714 False
i== 8 26./ 8== 3.250000 65./ 8== 8.125000 False
i== 9 26./ 9== 2.888889 65./ 9== 7.222222 False
i== 10 26./10== 2.600000 65./10== 6.500000 False
i== 11 26./11== 2.363636 65./11== 5.909091 False
i== 12 26./12== 2.166667 65./12== 5.416667 False
i== 13 26./13== 2.000000 65./13== 5.000000 True
- elif part is not active -
- 26/65 returned by if section -
frac == 26/65
---------------------------------------
n == 49 d == 98
float('49'[0]) == 4.000000 float('98'[1]) == 8.000000
i== 2 49./ 2== 24.500000 98./ 2== 49.000000 False
i== 3 49./ 3== 16.333333 98./ 3== 32.666667 False
i== 4 49./ 4== 12.250000 98./ 4== 24.500000 False
i== 5 49./ 5== 9.800000 98./ 5== 19.600000 False
i== 6 49./ 6== 8.166667 98./ 6== 16.333333 False
i== 7 49./ 7== 7.000000 98./ 7== 14.000000 False
i== 8 49./ 8== 6.125000 98./ 8== 12.250000 False
i== 9 49./ 9== 5.444444 98./ 9== 10.888889 False
i== 10 49./10== 4.900000 98./10== 9.800000 False
i== 11 49./11== 4.454545 98./11== 8.909091 False
i== 12 49./12== 4.083333 98./12== 8.166667 False
i== 13 49./13== 3.769231 98./13== 7.538462 False
i== 14 49./14== 3.500000 98./14== 7.000000 False
i== 15 49./15== 3.266667 98./15== 6.533333 False
i== 16 49./16== 3.062500 98./16== 6.125000 False
i== 17 49./17== 2.882353 98./17== 5.764706 False
i== 18 49./18== 2.722222 98./18== 5.444444 False
i== 19 49./19== 2.578947 98./19== 5.157895 False
i== 20 49./20== 2.450000 98./20== 4.900000 False
i== 21 49./21== 2.333333 98./21== 4.666667 False
i== 22 49./22== 2.227273 98./22== 4.454545 False
i== 23 49./23== 2.130435 98./23== 4.260870 False
i== 24 49./24== 2.041667 98./24== 4.083333 False
i== 25 49./25== 1.960000 98./25== 3.920000 False
i== 26 49./26== 1.884615 98./26== 3.769231 False
i== 27 49./27== 1.814815 98./27== 3.629630 False
i== 28 49./28== 1.750000 98./28== 3.500000 False
i== 29 49./29== 1.689655 98./29== 3.379310 False
i== 30 49./30== 1.633333 98./30== 3.266667 False
i== 31 49./31== 1.580645 98./31== 3.161290 False
i== 32 49./32== 1.531250 98./32== 3.062500 False
i== 33 49./33== 1.484848 98./33== 2.969697 False
i== 34 49./34== 1.441176 98./34== 2.882353 False
i== 35 49./35== 1.400000 98./35== 2.800000 False
i== 36 49./36== 1.361111 98./36== 2.722222 False
i== 37 49./37== 1.324324 98./37== 2.648649 False
i== 38 49./38== 1.289474 98./38== 2.578947 False
i== 39 49./39== 1.256410 98./39== 2.512821 False
i== 40 49./40== 1.225000 98./40== 2.450000 False
i== 41 49./41== 1.195122 98./41== 2.390244 False
i== 42 49./42== 1.166667 98./42== 2.333333 False
i== 43 49./43== 1.139535 98./43== 2.279070 False
i== 44 49./44== 1.113636 98./44== 2.227273 False
i== 45 49./45== 1.088889 98./45== 2.177778 False
i== 46 49./46== 1.065217 98./46== 2.130435 False
i== 47 49./47== 1.042553 98./47== 2.085106 False
i== 48 49./48== 1.020833 98./48== 2.041667 False
i== 49 49./49== 1.000000 98./49== 2.000000 False
- elif part is not active -
- No convenient divisor found for 49 98 : returned by else section -
frac == No convenient divisor found for 49 98
can't record 'No'==frac[0:2] as numerator
detected :
16/64
19/95
26/65
No convenient divisor found for 49 98
nums == ['16', '19', '26']
denoms == ['64', '95', '65']
pro,duct == 7904 395200
Fraction(pro, duct) == 1/50
The elapsed time is 2.40599989891 seconds.
ELIF = 1
---------------------------------------
n == 16 d == 64
float('16'[0]) == 1.000000 float('64'[1]) == 4.000000
i== 2 16./ 2== 8.000000 64./ 2== 32.000000 False
- elif part is active -
Fraction('1/4') == 1/4
Fraction(16, 64) == 1/4
- 1664 returned by elif section -
frac == 1664
---------------------------------------
n == 19 d == 95
float('19'[0]) == 1.000000 float('95'[1]) == 5.000000
i== 2 19./ 2== 9.500000 95./ 2== 47.500000 False
- elif part is active -
Fraction('1/5') == 1/5
Fraction(19, 95) == 1/5
- 1995 returned by elif section -
frac == 1995
---------------------------------------
n == 26 d == 65
float('26'[0]) == 2.000000 float('65'[1]) == 5.000000
i== 2 26./ 2== 13.000000 65./ 2== 32.500000 False
- elif part is active -
Fraction('2/5') == 2/5
Fraction(26, 65) == 2/5
- 2665 returned by elif section -
frac == 2665
---------------------------------------
n == 49 d == 98
float('49'[0]) == 4.000000 float('98'[1]) == 8.000000
i== 2 49./ 2== 24.500000 98./ 2== 49.000000 False
- elif part is active -
Fraction('4/8') == 1/2
Fraction(49, 98) == 1/2
- 4998 returned by elif section -
frac == 4998
detected :
1664
1995
2665
4998
nums == ['16', '19', '26', '49']
denoms == ['64', '95', '65', '98']
pro,duct == 387296 38729600
Fraction(pro, duct) == 1/100
The elapsed time is 6.40599989891 seconds.
当 ELIF 为假时,
结果16/64 19/95 26/65
由if section
返回,格式背叛了此来源。
当 ELIF 为True时,
结果1664 1995 2665 4998
由elif section
返回,它也以格式显示
由elif section
返回的这一事实使您得出结论if section
未运行。
你的结论是错误的,因为你错误地认为
“在两种情况下都满足if语句的条件”
不,它们不是,因为您不允许循环测试i
的所有可能值:对于第一个值i==2
,测试结果始终为False,则elif section
总是在第一个值之后输入(nikie已经解释了这个)
输入的值是相同的,但是不能满足使证据相同所需的条件。
为了给循环提供完全运行的可能性,有必要取消elif section
,。
请注意,在以下代码中,在frac[0:2]
中添加nums
并在frac[-2:]
中添加denoms
允许执行因错误而停止,并且结果是您正在等待的结果:16/64 19/95 26/65 4998
def curious(numer,denom,disp=None):
n = str(numer)
d = str(denom)
fracs = []
if n!=d and n[1] == d[0]:
ELIF = 1
fn0 = float(n[0])
fd1 = float(d[1])
if disp:
print ('---------------------------------------\n'
'n == %s d == %s\n'
"float('%s'[0]) == %f float('%s'[1]) == %f"
% ( n,d,n,fn0,d,fd1 ) )
for i in range(2, numer+1):
if disp:
print ('i== %2d '
'%s./%2d==%10f %s./%2d==%10f %s' %
(i,n,i,float(n)/i,d,i,float(d)/i,
float(n)/i==fn0 and float(d)/i==fd1) )
if float(numer)/i==fn0 and float(denom)/i==fd1:
if disp:
print (' %s\n'
' - %s/%s returned by if section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n,d))
return n + "/" + d
if ELIF and d[1] != "0":
if Fraction( n[0] + '/' + d[1] ) \
== \
Fraction(numer, denom):
if disp:
print (' %s\n'
" Fraction('%s/%s') == %s\n"
" Fraction(%s, %s) == %s\n"
' - %s%s returned by elif section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n[0],d[1],Fraction( n[0] + '/' + d[1] ),
numer,denom,Fraction(numer, denom),n,d) )
return n + d
else:
if n+d=='4998':
if disp:
print (' - elif part is active -' if ELIF
else ' - elif part is not active -')
print ' - No convenient divisor found for 49 98 : returned by else section -'
return 'No convenient divisor found for 49 98'
显示器
(skiped lines)
---------------------------------------
n == 26 d == 65
float('26'[0]) == 2.000000 float('65'[1]) == 5.000000
i== 2 26./ 2== 13.000000 65./ 2== 32.500000 False
i== 3 26./ 3== 8.666667 65./ 3== 21.666667 False
i== 4 26./ 4== 6.500000 65./ 4== 16.250000 False
i== 5 26./ 5== 5.200000 65./ 5== 13.000000 False
i== 6 26./ 6== 4.333333 65./ 6== 10.833333 False
i== 7 26./ 7== 3.714286 65./ 7== 9.285714 False
i== 8 26./ 8== 3.250000 65./ 8== 8.125000 False
i== 9 26./ 9== 2.888889 65./ 9== 7.222222 False
i== 10 26./10== 2.600000 65./10== 6.500000 False
i== 11 26./11== 2.363636 65./11== 5.909091 False
i== 12 26./12== 2.166667 65./12== 5.416667 False
i== 13 26./13== 2.000000 65./13== 5.000000 True
- elif part is active -
- 26/65 returned by if section -
frac == 26/65
---------------------------------------
n == 49 d == 98
float('49'[0]) == 4.000000 float('98'[1]) == 8.000000
i== 2 49./ 2== 24.500000 98./ 2== 49.000000 False
i== 3 49./ 3== 16.333333 98./ 3== 32.666667 False
i== 4 49./ 4== 12.250000 98./ 4== 24.500000 False
i== 5 49./ 5== 9.800000 98./ 5== 19.600000 False
i== 6 49./ 6== 8.166667 98./ 6== 16.333333 False
i== 7 49./ 7== 7.000000 98./ 7== 14.000000 False
i== 8 49./ 8== 6.125000 98./ 8== 12.250000 False
i== 9 49./ 9== 5.444444 98./ 9== 10.888889 False
i== 10 49./10== 4.900000 98./10== 9.800000 False
i== 11 49./11== 4.454545 98./11== 8.909091 False
i== 12 49./12== 4.083333 98./12== 8.166667 False
i== 13 49./13== 3.769231 98./13== 7.538462 False
i== 14 49./14== 3.500000 98./14== 7.000000 False
i== 15 49./15== 3.266667 98./15== 6.533333 False
i== 16 49./16== 3.062500 98./16== 6.125000 False
i== 17 49./17== 2.882353 98./17== 5.764706 False
i== 18 49./18== 2.722222 98./18== 5.444444 False
i== 19 49./19== 2.578947 98./19== 5.157895 False
i== 20 49./20== 2.450000 98./20== 4.900000 False
i== 21 49./21== 2.333333 98./21== 4.666667 False
i== 22 49./22== 2.227273 98./22== 4.454545 False
i== 23 49./23== 2.130435 98./23== 4.260870 False
i== 24 49./24== 2.041667 98./24== 4.083333 False
i== 25 49./25== 1.960000 98./25== 3.920000 False
i== 26 49./26== 1.884615 98./26== 3.769231 False
i== 27 49./27== 1.814815 98./27== 3.629630 False
i== 28 49./28== 1.750000 98./28== 3.500000 False
i== 29 49./29== 1.689655 98./29== 3.379310 False
i== 30 49./30== 1.633333 98./30== 3.266667 False
i== 31 49./31== 1.580645 98./31== 3.161290 False
i== 32 49./32== 1.531250 98./32== 3.062500 False
i== 33 49./33== 1.484848 98./33== 2.969697 False
i== 34 49./34== 1.441176 98./34== 2.882353 False
i== 35 49./35== 1.400000 98./35== 2.800000 False
i== 36 49./36== 1.361111 98./36== 2.722222 False
i== 37 49./37== 1.324324 98./37== 2.648649 False
i== 38 49./38== 1.289474 98./38== 2.578947 False
i== 39 49./39== 1.256410 98./39== 2.512821 False
i== 40 49./40== 1.225000 98./40== 2.450000 False
i== 41 49./41== 1.195122 98./41== 2.390244 False
i== 42 49./42== 1.166667 98./42== 2.333333 False
i== 43 49./43== 1.139535 98./43== 2.279070 False
i== 44 49./44== 1.113636 98./44== 2.227273 False
i== 45 49./45== 1.088889 98./45== 2.177778 False
i== 46 49./46== 1.065217 98./46== 2.130435 False
i== 47 49./47== 1.042553 98./47== 2.085106 False
i== 48 49./48== 1.020833 98./48== 2.041667 False
i== 49 49./49== 1.000000 98./49== 2.000000 False
- elif part is active -
Fraction('4/8') == 1/2
Fraction(49, 98) == 1/2
- 4998 returned by elif section -
frac == 4998
detected :
16/64
19/95
26/65
4998
nums == ['16', '19', '26', '49']
denoms == ['64', '95', '65', '98']
pro,duct == 387296 38729600
Fraction(pro, duct) == 1/100
The elapsed time is 2.45300006866 seconds.
然而,格式的差异背叛了另一个部分(elif section
)返回的最后一个值,而不是3个第一个值(由if section
返回)。
这值得澄清
显示屏显示i
49./i
4
98./i
和8
n[0]==4
没有值n==49
:这意味着没有理由d[1]==8
将是d==98
和49./i==1.0 and 98.i==2.00
除数49/98
的除数。
所以问题的根源不是用二进制表示来表示精确十进制值的不可能性(导致难以在浮点运算中进行比较),这是一个算法问题。
只有在执行测试if section
时,才会返回值elif section
,并else section
将其视为3个第一个值。所以我认为以下代码具有正确的算法。但是,if section
和elif section
都没有执行,无论给予 ELIF 的值是什么;这仅表示Fraction
中的算法与def curious(numer,denom,disp=None):
n = str(numer)
d = str(denom)
fracs = []
if n!=d and n[1] == d[0]:
ELIF = 1
fn0 = float(n[0])
fd1 = float(d[1])
GCD = gcd(fn0,fd1)
fn0DD = fn0/GCD
fd1DD = fd1/GCD
if disp:
print ('---------------------------------------\n'
'n == %s d == %s\n'
"float('%s'[0]) == %f float('%s'[1]) == %f"
% ( n,d,n,fn0,d,fd1 ) )
for i in range(2, numer+1):
if disp:
print ('i== %2d '
'%s./%2d==%10f %s./%2d==%10f %s' %
(i,n,i,float(n)/i,d,i,float(d)/i,
float(n)/i==fn0DD and float(d)/i==fd1DD) )
if float(numer)/i==fn0DD and float(denom)/i==fd1DD:
if disp:
print (' %s\n'
' - %s/%s returned by if section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n,d))
return n + "/" + d
if ELIF and d[1] != "0":
if Fraction( n[0] + '/' + d[1] ) \
== \
Fraction(numer, denom):
if disp:
print (' %s\n'
" Fraction('%s/%s') == %s\n"
" Fraction(%s, %s) == %s\n"
' - %s%s returned by elif section -' %
('- elif part is active -' if ELIF
else '- elif part is not active -',
n[0],d[1],Fraction( n[0] + '/' + d[1] ),
numer,denom,Fraction(numer, denom),n,d) )
return n + d
中(skipped lines)
i== 44 49./44== 1.113636 98./44== 2.227273 False
i== 45 49./45== 1.088889 98./45== 2.177778 False
i== 46 49./46== 1.065217 98./46== 2.130435 False
i== 47 49./47== 1.042553 98./47== 2.085106 False
i== 48 49./48== 1.020833 98./48== 2.041667 False
i== 49 49./49== 1.000000 98./49== 2.000000 True
- elif part is active -
- 49/98 returned by if section -
frac == 49/98
detected :
16/64
19/95
26/65
49/98
nums == ['16', '19', '26', '49']
denoms == ['64', '95', '65', '98']
pro,duct == 387296 38729600
Fraction(pro, duct) == 1/100
The elapsed time is 2.39100003242 seconds.
的原则相同。
{{1}}等待显示
{{1}}