欧拉计划为什么说我得错了20号?

时间:2011-11-24 05:11:55

标签: python

以下是我要解决的问题:Euler 20

  

n!表示n ⨉ (n - 1) ⨉ ... ⨉ 3 ⨉ 2 ⨉ 1

     

例如,10! = 10 ⨉ 9 ⨉ ... ⨉ 3 ⨉ 2 ⨉ 1 = 3628800,   数字10!中的数字总和为3 + 6 + 2 + 8 + 8 + 0 + 0 = 27

     

查找数字100!

中的数字总和

我试过这个:

y = 1  #The actual number
sum = 0 #The sum of its digits.

def factorial(x): #Calculates the number using a recursive factorial algorithm
    global y
    y = y*x
    if x > 1:
        factorial(x-1)
    else:
        return 0

factorial(100) #Calculate 100! and the function will put it in y.

def count(): #Calculates the sum.
    global y, sum
    while y > 0:
        currentDigit = int(y) % 10 #Find the remainder of the number gives the very last digit
        sum = sum + currentDigit #Add that to the total sum.
        y = int(y) / 10 #Divide y by 10 knocking of the 1s-digit place and putting the 10s digit in its place.
    return sum #return the sum.

print(count()) #print the count.

如果我做factorial(10)而不是100我得到27这就是我应该得到的问题,但我得到factorial(100) 675,程序说这是错误的。我做错了什么?我对Python并不熟悉,抱歉,如果我犯了一个愚蠢的错误。

5 个答案:

答案 0 :(得分:5)

问题在于count的实施,特别是行:

    y = int(y) / 10

自Python 3起,/true division。在Python 2.2及更高版本中,您可以使用from __future__ import division获得Python 3的除法行为。执行上面的行后,y是一个浮点数。大多数系统上的Python浮点数只有大约15个有效十进制数字(sys.float_info.dig将为您提供系统的精度;请注意,实际上有53个的精度,等于53 / log 2 (10)≈15.955)。 count在那些重要的数字之后提取的任何十进制数字是舍入误差的结果,并且是将base-2 float转换为base 10的结果。在一定长度上,中间数字将不会对总和产生影响由count计算。

[count(int('8' * 17 + str(k) + '0')) for k in range(1, 10)]
# [130, 130, 130, 130, 130, 130, 130, 130, 130]
import random
[count(int('8' * 17 + ('%05d' % random.randint(1,99999)) + '0')) for k in range(1, 10)]
# [146, 146, 146, 146, 146, 146, 146, 146, 146]

解决方案是使用//进行整数除法,此时您还可以删除int次转化。在您使用它的同时,您也可以ycount添加参数,并使sum为本地参数。否则,您的全局sum变量将隐藏内置的sum函数。

至于取消y中的全局factorial,传递额外参数很容易:

def factorial(x, p=1):
    p *= x
    if x > 1:
        return factorial(x-1, p)
    else:
        return p

这具有tail-recursive的优势。标准python解释器不实现尾调用优化,但可以使用装饰器完成。将这样的装饰器应用于factorial,结果是一个不会导致堆栈溢出的函数。这种传递累积的技术可以用于许多其他函数来创建尾递归函数。

或者,写一个迭代版本,这是一个更加pythonic。

答案 1 :(得分:4)

这是一种简单的方法来重写factorial()函数,使其不再依赖于全局变量:

>>> def fac(x):
...   if x > 1:
...     return x * fac(x-1)
...   else:
...     return 1
... 
>>> fac(10)
3628800
>>> fac(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L

它依赖于返回值并递归调用自身来执行计算。当然,计算100!意味着调用链将是100级深度,但为了清楚这一功能,我认为这种权衡非常值得。 (可能有更强大的方法来编写这个函数 - 例如,更好地处理负数或非整数。)

有几种方法可以找到数字的总和 - 考虑将大数字看作单个字符串,遍历所有字符,并总结数字和<的整数值的方法/ em>将数字视为数字的方法,找到其十进制表示中最低位的值,并在您考虑该数字后删除该最低位数。这两种方法都有效。

至于你夏天的实际错误,我希望这是有教育意义的:

$ python3.2 -c "print (755 / 10)"
75.5
$ python2.7 -c "print (755 / 10)"
75

答案 2 :(得分:0)

找到数字100中的数字之和!

def sumFactorial(n):
    factorial=str(reduce(lambda x,y:x*y, range(n,0,-1))) 
    return sum(int(x) for x in factorial)

>>> sumFactorial(10)
27
>>> sumFactorial(100)
648
>>> 

答案 3 :(得分:0)

//In c++
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
    int a[200];
    int carry=0,temp,m=1,k=0;
    int n;
    cin>>n;
    a[0]=1;
    for(int i=1;i<=n;i++)
    {
        k=0;
        for(int j=0;j<m;j++)
        {
            temp=a[j]*i+carry;  
            a[j]=temp%10;
            carry=temp/10;

        }
        while(carry!=0)
        a[m++]=carry%10,carry/=10;

    }
    long long ans=0;
    for(int i=m-1;i>=0;i--)
    {
    ans+=a[i];
    }
    cout<<endl;
    cout<<ans<<endl;
}
1.Array a[200] is used to store the digits of factorial.
2.Outer loop run from 1..100
3.varible m indicates no of digits in array or factorial
4.now lets take a example
  take a simple multiplication
  25 x 12
-------------
   5 0
 2 5
-------------
 3 0 0
300- value stores in temp;
by taking modulo 10 we can get the last digit it is placed array
300/10 becomes carry.

答案 4 :(得分:0)

我发现你使用了很多全局变量。

首先要做的事情:

我认为您可以在函数中使用public ActionResult Customize( int id ) { var template = Persistence.Data.RetrieveObject<Template>( id ); var model = new Customization(); ViewBag.Template = template; this.ViewData.ModelState.Clear(); // add that after you consume the ModelState return ( View( model ) ); } 而不是使用global y,而是返回值y

此外,我认为您可以使用built-in functions而不是自己构建新功能。请记住,使用内置函数比我们创建的函数更有效。我并不是说你创建的函数效率不高(实际上你创建的阶乘函数有一个非常有效的实现),但有时与我们创建的函数相比,内置函数的效率更高。

您可以从factorial function导入math module,而不是编写新的阶乘函数。

return y

要将您的号码分成数字,您可以执行以下操作:

>>> from math import factorial

正如您所看到的,我们正在将数字转换为字符串,将其分解,因此列表中的数字形式为字符串。所以你应该再将它转换回int。要做到这一点:

>>> a = list(str(factorial(100)))

我在上面的代码中使用了list comprehension

最后使用内置sum function来获得解决方案。

>>> a = [int(x) for x in a]