Manuel Mannhardt
Manuel Mannhardt

Reputation: 2201

Euler Project Problem #17 - Bug in my code

So I am solving the problems from projecteuler.net at the moment and with the 17th problem I got a problem with having a length 100 greater than the actual solution.

The description of the problem is as follows:

If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?

NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.

And for my code, I have this one:

def problem17(max):
    numbers = {
        0:  0,
        1 : len('one'),
        2 : len('two'),
        3 : len('three'),
        4 : len('four'),
        5 : len('five'),
        6 : len('six'),
        7 : len('seven'),
        8 : len('eight'),
        9 : len('nine'),
        10: len('ten'),
        11: len('eleven'),
        12: len('twelve'),
        13: len('thirteen'),
        14: len('fourteen'),
        15: len('fifteen'),
        16: len('sixteen'),
        17: len('seventeen'),
        18: len('eighteen'),
        19: len('nineteen')
    }

    number_tenths = {
        2: len('twenty'),
        3: len('thirty'),
        4: len('fourty'),
        5: len('fifty'),
        6: len('sixty'),
        7: len('seventy'),
        8: len('eighty'),
        9: len('ninety')
    }

    hundred = len('hundred')
    thousand = len('thousand')
    andl = len('and')

    i = 1
    length = 0
    under_onehundred = lambda i: numbers[i] if i < 20 else number_tenths[math.floor(i / 10)] + numbers[i % 10]
    hundreds = lambda i: numbers[math.floor(i / 100)] + hundred
    while i <= max:
        if i < 100:
            length += under_onehundred(i)
        elif i % 100 == 0 and i % 1000 != 0:
            length += hundreds(i)
        elif i >= 100 and i < 1000:
            length += hundreds(i) + andl + under_onehundred(i % 100)
        elif i % 1000 == 0:
            length += numbers[math.floor(i / 1000)] + thousand

        i += 1

    return length

Which will output 21224 instead of the correct answer if I call it with problem17(1000).

Edit: I´m pretty new to python, so I there is anything in general, which I could improve, please let me know in a comment!

My question is, what is wrong with my code?

Upvotes: 0

Views: 167

Answers (2)

gelonida
gelonida

Reputation: 5630

One problem might be:

hundreds = lambda n: numbers[math.floor(i / 100)] + hundred

which should be:

hundreds = lambda n: numbers[math.floor(n / 100)] + hundred

Another problem might be the spelling of 40, which should be "forty" and not "fourty"

Upvotes: 3

kaya3
kaya3

Reputation: 51034

I don't think this is the only problem with your code, but it's a straightforward one: don't use is or is not on numbers; use == or != instead. You may be surprised by the following behaviour:

>>> 1000 + 2000 is 3000
False
>>> 1000 + 2000 == 3000
True

Explanation: the == operator tests for equality, but is tests for object identity. In this example, there are two different int objects which equal 3000, but they are not the same object, so is gives False.

Upvotes: 4

Related Questions