Project Euler 145的小案例没有得到预期的结果

时间:2012-02-01 04:31:50

标签: python python-2.7

所以我正在Project Euler 145工作,其中说:

  

一些正整数n具有总和[ n + reverse(n) ]完全由奇数(十进制)数字组成的属性。例如,36 + 63 = 99409 + 904 = 1313。我们称这些数字是可逆的;所以36,63,409和904是可逆的。 n或反向(n)中不允许前导零。

     

有120个可逆数字低于一千。

     

有多少可逆数字低于十亿(10 ** 9)?

我正在尝试以下代码(而不是使用10 ^ 9我使用10来检查结果(应该为零)是否正在发生:

def check(x):
    y = int(str(x)[::-1]) #x backwards
    #add the rev number to the original number (convert them to a list)
    xy = list(str(x+y))
    #a list of even digits.
    evens = ['0', '2', '4', '6', '8']
    #check if the number has any digits using intersection method.
    intersect = set(xy).intersection(set(evens))
    if not intersect:
        #if there was no intersection the digits must be all odd.
        return True
    return False

def firstCheck(x):
    if (int(str(x)[:1])+(x%10))%2 == 0:
        #See if first number and last number of x make an even number.
        return False
    return True

def solve():
    L = range(1, 10) #Make a list of 10
    for x in L:
        if firstCheck(x) == False:
            #This quickly gets rid of some elements, not all, but some.
            L.remove(x)
    for x in L:
        if check(x) == False:
            #This should get rid of all the elements.
            L.remove(x)
    #what is remaining should be the number of "reversible" numbers.
    #So return the length of the list.
    return len(L)

print solve()

它分为两部分:在方法solve中有一个firstCheckcheck第一个检查是快速消除一些数字(所以当我制作一个10 ^ 9大小时列表我可以释放一些RAM)。第二个检查是摆脱所谓的不是“可逆数字”的所有数字的检查。在第一次检查中,我只看到第一个和最后一个数字是否为偶数,并消除该数字。在检查方法中,我反转数字,将两个数字加在一起并将它们放入一个列表中,然后检查它是否与一个平均列表相交,如果它确实从列表中消除了它。结果列表应该是“可逆”数字的元素数,因此我将列表并返回其长度。对于range(1,10),我得到2作为结果(而不是所需的零)。它没有消除的数字[4,8],我似乎无法找出原因。

2 个答案:

答案 0 :(得分:1)

我可以看到两个问题。

首先,您(两次)修改您正在迭代的列表:

for x in L:
    if firstCheck(x) == False:
        #This quickly gets rid of some elements, not all, but some.
        L.remove(x)

这将导致出乎意料且难以预测的行为。迭代列表的副本或简单地使用列表解析进行过滤:

L = [x for x in L if firstCheck(x)]

其次,你没有检查消除任何前导零,所以当它应该为假时,check(10)为True。修复后,您的代码似乎有效:

>>> len(solve(10))
0
>>> len(solve(1000))
120

[我刚添加了一个参数来选择范围。]

答案 1 :(得分:0)

Java解决方案,需要3分钟

public class Euler145 {

public static void main(String[] args) {

  int i, j, add, convert, count = 0;
  String get;
  StringBuilder rev;

 for ( i=0; i <= 1000000000; i++) {
        get = "" + i;
        rev = new StringBuilder(get);
        rev.reverse():
        convert = Integer.parseInt(rev.toString());
        add = convert + i;

        if (add % 2 != 0)  {

            while (add > 0)  {
                 j = add % 10;

                 if (j == 1 || j == 3 || j == 5 || j == 7 || j == 9)  {
                    add /= 10;
                    String leadZero = "" + i;
                    if (j == 0 && !leadZero.endsWith("0"))  {
                        count++;
                    }
                   }  else  {
                     break;
                 }
            }
        }
   }
      System.out.println(count);
 }
}