No se obtienen los resultados esperados para el caso más pequeño del Proyecto Euler 145

So I am work on Proyecto Euler 145 Que dice:

Some positive integers n have the property that the sum [ n + reverse(n) ] consists entirely of odd (decimal) digits. For instance, 36 + 63 = 99 y la 409 + 904 = 1313. We will call such numbers reversible; so 36, 63, 409, and 904 are reversible. Leading zeroes are not allowed in either n or reverse(n).

There are 120 reversible numbers below one-thousand.

How many reversible numbers are there below one-billion (10**9)?

I am trying the following code (and instead of using 10^9 I am using 10 to check if the result (which should be zero) is happening:

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()

It works in two parts: In the method solve hay un firstCheck y la check the first check is to eliminate some numbers quickly (so when I make a 10^9 size list I can free some RAM). The second check is the one that gets rid of all the numbers supposedly that are not "reversible numbers". In the first check I just see if the first and last digit make an even number, and eliminate that number. In the check method I reverse the number, add the two numbers together and make them into a list, then check if it intersects a list of evens, if it does eliminate it from the list. The resulting list should be the number of elements that are "reversible" numbers so I take the list and return its length. For range(1,10) I get 2 as the result (as opposed to the desired zero). And the numbers it doesn't eliminate [4,8] and I can't seem to find out why.

preguntado el 01 de febrero de 12 a las 04:02

Notes: 1. You can avoid any space concerns by contando instead of managing lists, that's also faster. 2. This approach is slow and doesn't scale well, by analysing the conditions you can get a solution that returns the answer instantaneously even for bounds like 10^20. -

2 Respuestas

I can see two problems.

First, you (twice) modify a list that you're iterating over:

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

This will lead to unexpected and hard-to-predict behaviour. Either iterate over a copy of the list or simply filter using a list comprehension:

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

etc.

Second, you're not checking to eliminate any leading zeros, so check(10) is True when it should be False. After fixing those, your code seems to work:

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

[I just added a parameter to choose the range.]

Respondido 01 Feb 12, 08:02

@anon: "Leading zeroes are not allowed in either n or reverse(n)." - DSM

Oh, wait, I misread, I thought that it was saying that like ther were leading zeros they wouldn't be allowed so eliminate the zeros and then do it... - sobre

PS: "something == False" is much less pythonic than "not something". - DSM

Java solution and it takes 3 minutes

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);
 }
}

respondido 20 nov., 16:10

This question is about Python - Nombre

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.