开发者

Project Euler Problem 17 Python

Please let me know how to bug fix this code . I tried and correct a lot of things , but I am 10 extra to the solution !

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.

My solution

sd={0:0,1: 3, 2: 3, 3: 5, 4: 4, 5: 4, 6: 3, 7: 5, 8: 5, 9: 4}
dd1={10:3,11:6,12:6,13:8,14:8,15:7,16:7,17:9,18:9,19:8}
dd2={2:6,3:6,4:5,5:5,6:5,7:7,8:6,9:6}
td= {0: 10, 1: 13, 2: 13, 3: 15, 4: 14, 5: 14, 6: 13, 7: 15, 8: 15, 9: 14}
cd={0:0,1: 3, 2: 3, 3: 5, 4: 4, 5: 4, 6: 3, 7: 5, 8: 5, 9:    4,10:3,11:6,12:6,13:8,14:8,15:7,16:7,17:9,18:9,19:8}


def cw(n) :

  if n/10 == 0 开发者_Go百科:               # If the number is less than 10 execute this section                               
   return sd[n%10]

       elif n/100 == 0 :           # If the number is less than 100 execute this section
   if n<20 :
    return(dd1[n])         # Directly map to dd1 
   else :
    return(dd2[n/10]+sd[n%10])  # If the number is > 20 do a construction 
  elif n/1000==0 :               
   if n%100==0:
    return sd[n/100] + 7        # If the number is multiples of 100 give assuming single digit and 7 for hundred 
   elif n%100 < 20 :
    return td[n/100] + cd[n%100]  # If 3 digit numbers not more than *20 , then direct mapping 
   else :
    return td[n/100] + dd2[(n%100)/10] + sd[n%10]

count = 0 
for i in range(1,1000) : 
 count = count + cw(i)
print count + 11

I am getting 21134 and the answer is... (SPOILER: please hover over next line to view)

21124

VERY ANNOYING !


The word "eighteen" only has eight letters, not nine. Since it appears ten times in the range 1-1000, that would explain the discrepancy.

By the way, if you're checking if n is less than 10, why not simply use n<10 instead of n/10 == 0?


Well, the code you give is way too full of mysterious numbers. As another poster suggested, you'd be better off having the computer tally up the lengths of the various words for the tables of number words. An opinion: as written, there's nothing about your code that I can imagine would ever be useful for anything but this Project Euler problem. The approach that I took was to write a function "num2words(i)" that given an integer i, returns the words for i. Then the main loop just converts each of the numbers 1 through 1000 to words and sums up the length of the words, using a regular expression to exclude the blanks from the tally, counting only the letters. Performance was quite acceptable and I assert my approach was easier to debug too. And while I have no burning need elsewhere for num2words at present, I can at least imagine being able to re-use that code someday, perhaps in a check-printing program.

My num2words routine, by the way uses itself recursively by breaking off the leading digits of big numbers (e.g. kddd) and figuring num2words(k) + " thousand" and if the remaining digits are not zero, tagging on +" "+num2words(ddd). The code to handle hundreds is similar. It would be straight forward to add code for millions.

Speaking of mysterious numbers, why does your main loop stop at 999 and then adjust the final total by 11 to count the letters in "one thousand"? Suppose someone was asked to convert your program to deal with numbers in another language. What are the chances of them catching the adjustment needed to that +11 at the end?

In my opinion, if your objective in solving Project Euler problems is just to arrive at the right answer, you are missing out on much of the educational value of working the problems. Aim to develop good clean code. Even after your code produces the correct answer, sit and re-read your code and try to make it better (e.g. easier to read, more "Pythonic", something you'd be proud to show to a programmer friend).


This is my approach to this problem

# Number letter counts
def e17():
    n1=(0,3,3,5,4,4,3,5,5,4)    # 1 to 9
    n10=(0,3,6,6,5,5,5,7,6,6)   # 10 to 90
    n11=(0,6,6,8,8,7,7,9,8,8)   # 11 to 19
    n=(7,10,11) # hundred, hundred and, one thousand

    n1to99x10 = (sum(n1)*9 + n10[1] + sum(n11) + sum(n10[2:])*10)*10 # from 1 to 99 all
    n100to900all = n[0]*9 + n[1]*99*9 + sum(n1)*100 # from 100 to 900
    
    letters = n1to99x10 + n100to900all + n[2]
    return letters
print(e17())    # 21124 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜