2015-10-17 37 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,但沒關係,你可以處理,並跳過它。

想想如果你不得不把代碼寫到一百萬的話會發生什麼。什麼似乎重複?將該代碼拉出並製作更多功能。

相關問題