简体   繁体   English

Project Euler 问题 17 Python

[英]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 !我尝试并纠正了很多事情,但我对解决方案多出了 10 分!

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.如果数字 1 到 5 用单词写出:一、二、三、四、五,那么总共使用了 3 + 3 + 5 + 4 + 4 = 19 个字母。

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?如果从 1 到 1000(一千)的所有数字都用文字写出来,会用多少个字母?

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.例如,342(三百四十二)包含 23 个字母,115(一百一十五)包含 20 个字母。 The use of "and" when writing out numbers is in compliance with British usage.写出数字时使用“and”符合英国的用法。

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 :               # 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)我收到 21134 答案是...(剧透:请悬停在下一行查看)

21124 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.由于它在 1-1000 的范围内出现了 10 次,这就解释了这种差异。

By the way, if you're checking if n is less than 10, why not simply use n<10 instead of n/10 == 0 ?顺便说一句,如果您要检查 n 是否小于 10,为什么不简单地使用n<10而不是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.一个意见:正如所写的那样,除了这个 Project Euler 问题之外,我可以想象你的代码没有任何用处。 The approach that I took was to write a function "num2words(i)" that given an integer i, returns the words for i.我采用的方法是编写一个函数“num2words(i)”,该函数给出一个整数 i,返回 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.然后主循环只是将每个数字 1 到 1000 转换为单词并总结单词的长度,使用正则表达式从计数中排除空白,只计算字母。 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.虽然我目前在其他地方不需要 num2words,但我至少可以想象有一天能够重新使用该代码,也许在支票打印程序中。

My num2words routine, by the way uses itself recursively by breaking off the leading digits of big numbers (eg kddd) and figuring num2words(k) + " thousand" and if the remaining digits are not zero, tagging on +" "+num2words(ddd).顺便说一句,我的 num2words 例程通过断开大数字的前导数字(例如 kddd)并计算 num2words(k) + "千" 并且如果剩余数字不为零,则在 +" "+num2words(滴滴)。 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"?说到神秘数字,为什么你的主循环停在 999 处,然后将最终总数调整为 11 以计算“一千”中的字母? 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?他们最终获得+11所需调整的机会有多大?

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.在我看来,如果您解决 Project Euler 问题的目的只是为了得到正确的答案,那么您就错过了解决问题的大部分教育价值。 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 (eg easier to read, more "Pythonic", something you'd be proud to show to a programmer friend).即使在你的代码产生了正确的答案之后,坐下来重新阅读你的代码并尝试让它变得更好(例如更容易阅读,更“Pythonic”,你会很自豪地向程序员朋友展示一些东西)。

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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM