2015-10-17 36 views
2

我对编程非常陌生,无可否认,我的代码在批判中分享。此代码的工作原理和产生以下问题的正确答案(https://projecteuler.net/problem=17),但我希望我可以对如何使它不那么丑陋和简化,甚至从一个全新的角度来解决问题提出批评,以便我可以更好地从这个解决方案学习。非常感谢您的帮助!Project Euler no。 17 - 精简Python

# the final list that holds the string lengths 
addList = [] 

# dictionary holding integer:corresponding word pairs 
numbersDict = { 
0:"zero", 
1:"one", 
2:"two", 
3:"three", 
4:"four", 
5:"five", 
6:"six", 
7:"seven", 
8:"eight", 
9:"nine", 
10:"ten", 
11:"eleven", 
12:"twelve", 
13:"thirteen", 
14:"fourteen", 
15:"fifteen", 
16:"sixteen", 
17:"seventeen", 
18:"eighteen", 
19:"nineteen", 
20:"twenty", 
30:"thirty", 
40:"forty", 
50:"fifty", 
60:"sixty", 
70:"seventy", 
80:"eighty", 
90:"ninety" 
} 

### There has to be an easier way to do all this below ### 

def numberLetters(num): 

    letters = "" 

    if 0 < num <= 20: 
     letters += numbersDict[num] 

    if 21 <= num <= 99: 
     a,b = divmod(num, 10) 
     if b == 0: 
      letters += numbersDict[a*10] 
     else: 
      letters += numbersDict[a*10] + numbersDict[b] 

    if 100 <= num <= 999: 
     if num % 100 == 0: 
      letters += numbersDict[int(num/100)] + "hundred" 
     else: 
      digit = int(num/100) 
      num = num - digit * 100 
      if 0 < num <= 20: 
       letters += numbersDict[digit] + "hundredand" + numbersDict[num] 
      if 21 <= num <= 99: 
       a,b = divmod(num, 10) 
       if b == 0: 
        letters += numbersDict[digit] + "hundredand" + numbersDict[a*10] 
       else: 
        letters += numbersDict[digit] + "hundredand" + numbersDict[a*10] + numbersDict[b] 
    if num == 1000: 
     letters += "onethousand" 

    return letters 

for i in range(1,1001): 
    addList.append(len(numberLetters(i))) 
print(sum(addList)) 
+4

如果您想对工作代码进行批评,请在[Code Review](http://codereview.stackexchange.com/) – Blastfurnace

回答

0

这里是我的代码:

words = [ 
(1, 'one'  ,'' ), 
(2, 'two'  ,'' ), 
(3, 'three' ,'' ), 
(4, 'four'  ,'' ), 
(5, 'five'  ,'' ), 
(6, 'six'  ,'' ), 
(7, 'seven' ,'' ), 
(8, 'eight' ,'' ), 
(9, 'nine'  ,'' ), 
(10, 'ten'  ,'' ), 
(11, 'eleven' ,'' ), 
(12, 'twelve' ,'' ), 
(13, 'thirteen' ,'' ), 
(14, 'fourteen' ,'' ), 
(15, 'fifteen' ,'' ), 
(16, 'sixteen' ,'' ), 
(17, 'seventeen','' ), 
(18, 'eighteen' ,'' ), 
(19, 'nineteen' ,'' ), 
(20, 'twenty' ,'' ), 
(30, 'thirty' ,'' ), 
(40, 'forty' ,'' ), 
(50, 'fifty' ,'' ), 
(60, 'sixty' ,'' ), 
(70, 'seventy' ,'' ), 
(80, 'eighty' ,'' ), 
(90, 'ninety' ,'' ), 
(100, 'hundred' ,'and'), 
] 
words.reverse() 

def spell(n, i=0): 
    global words 
    word = "" 
    while n > 0: 
     for num in words[i:]: 
      if num[0] <= n: 
       div = n // num[0] 
       n = n % num[0] 
       if num[2]: word+=' '+spell(div,i) 
       word+=' '+num[1] 
       if num[2] and n: word+=' '+num[2] 
       break 
    return word[1:] 

count = lambda s: sum(1 for i in s if i!=' ') 
print(sum(count(spell(n)) for n in range(1001))) 

请注意,我用的是递归函数,那我加兼参数“我”拼,记录文字使用的最后一个索引,从而免去一些迭代中for num in words循环(确实不太有用,但它仅花费6个字符^^)。然后,我用一个多余的lambda函数来制作count函数,因为函数的名字是某种评论。 最后,我使用了生成器表达式的和函数count(spell(n)) for n in range(1001)。 如果删除' '+的所有匹配项并将len替换为len,则代码可能会更短,但使用此代码,您将拥有正确的spell函数。

如果你不明白在大胆的一个术语,那么你应该读一本书关于Python 3

如果你想抽出时间,你甚至可以memoize的拼写功能,或者做一个计数(咒语())你记忆的函数(因为字母计数整数比字符串轻)。

+0

上发帖,非常感谢,这非常有见地! –

0

您可以使用if/elif的

if 0 < num <= 20: 
    letters += numbersDict[num] 

elif 21 <= num <= 99: 

您也可以定义做任何事情,重复的功能。我也只是预先做所有的计算,不管它的范围。所以举例

digit = int(num/100) 

将结束与数字= 0为num = 55,但没关系,你可以处理,并跳过它。

想想如果你不得不把代码写到一百万的话会发生什么。什么似乎重复?将该代码拉出并制作更多功能。

相关问题