Проект Эйлера 17

Я пытался решить Эйлера 17 и столкнулся с некоторыми проблемами. Определение этой проблемы:

Если числа от 1 до 5 записаны словами: один, два, три, четыре, пять, то есть 3 + 3 + 5 + 4 + 4 = 19 букв, используемых в общей сложности.

Если бы все числа от 1 до 1000 (одна тысяча) включительно были написаны словами, сколько писем было бы использовано?

ПРИМЕЧАНИЕ. Не считайте пробелы или дефисы. Например, 342 (триста сорок два) содержит 23 буквы и 115 (сто пятнадцать) содержит 20 букв. Использование «и» при написании номеров соответствует британскому использованию.

Я написал его на Python, и даже после прохождения кода три или четыре раза я все еще не вижу, в чем проблема. Это долго (я только начал изучать питон, и я никогда не кодировал его раньше), но в основном я определял разные функции, которые принимают различное количество цифр и подсчитывают количество букв в каждом. В итоге я получил 21254, и кажется, что реальный ответ – 21124, так что я прочь ровно 130. Любая помощь будет оценена.

# create dict mapping numbers to their # lengths in English maps = {} maps[0] = 0 maps[1] = 3 maps[2] = 3 maps[3] = 5 maps[4] = 4 maps[5] = 4 maps[6] = 3 maps[7] = 5 maps[8] = 5 maps[9] = 4 maps[10] = 3 maps[11] = 6 maps['and'] = 3 maps['teen'] = 4 maps[20] = 6 maps[30] = 6 maps[40] = 5 maps[50] = 5 maps[60] = 6 maps[70] = 7 maps[80] = 6 maps[90] = 6 maps[100] = 7 maps[1000] = 8 # create a list of numbers 1-1000 def int_to_list(number): s = str(number) c = [] for digit in s: a = int(digit) c.append(a) return c # turn a number into a list of its digits def list_to_int(numList): s = map(str, numList) s = ''.join(s) s = int(s) return s L = [] for i in range(1,1001,1): L.append(i) def one_digit(n): q = maps[n] return q def eleven(n): q = maps[11] return q def teen(n): digits = int_to_list(n) q = maps[digits[1]] + maps['teen'] return q def two_digit(n): digits = int_to_list(n) first = digits[0] first = first*10 second = digits[1] q = maps[first] + one_digit(second) return q def three_digit(n): digits = int_to_list(n) first = digits[0] second = digits[1] third = digits[2] # first digit length f = maps[first]+maps[100] if second == 1 and third == 1: s = maps['and'] + maps[11] elif second == 1 and third != 1: s = digits[1:] s = list_to_int(s) s = maps['and'] + teen(s) elif second == 0 and third == 0: s = maps[0] elif second == 0 and third != 0: s = maps['and'] + maps[third] else: s = digits[1:] s = list_to_int(s) s = maps['and'] + two_digit(s) q = f + s return q def thousand(n): q = maps[1000] return q # generate a list of all the lengths of numbers lengths = [] for i in L: if i < 11: n = one_digit(i) lengths.append(n) elif i == 11: n = eleven(i) lengths.append(n) elif i > 11 and i < 20: n = teen(i) lengths.append(n) elif i > 20 and i < 100: n = two_digit(i) lengths.append(n) elif i >= 100 and i < 1000: n = three_digit(i) lengths.append(n) elif i == 1000: n = thousand(i) lengths.append(n) else: pass # since "eighteen" has eight letters (not 9), subtract 10 sum = sum(lengths) - 10 print "Your number is: ", sum 

One Solution collect form web for “Проект Эйлера 17”

Объяснение несоответствия

Ваш код пронизан ошибками:

  1. Это не верно:

     maps[60] = 6 

    Вклад в ошибку: +100 (потому что он действует от 60 до 69, от 160 до 169, …, от 960 до 969).

  2. Несколько подростков ошибаются:

     >>> teen(12) 7 >>> teen(13) 9 >>> teen(15) 8 >>> teen(18) 9 

    Вклад в ошибку: +40 (потому что он влияет на 12, 13, …, 112, 113, …, 918)

  3. И любой номер формы x10:

     >>> three_digit(110) 17 

    Вклад в error: 9 (потому что 110, 210, … 910)

  4. Число 20 не учитывается (вы считаете i < 20 и i > 20 но не i == 20 ).

    Вклад в error: -6

  5. Число 1000 написано «тысяча» на английском языке, но:

     >>> thousand(1000) 8 

    Вклад в error: -3

  6. Вы вычитаете 10 в конце, пытаясь компенсировать одну из этих ошибок.

    Вклад в error: -10

Общая погрешность: 100 + 40 + 9 – 6 – 3 – 10 = 130.

Как вы могли избежать этих ошибок

Пытаясь работать непосредственно с подсчетами писем, вам очень трудно проверить свою работу. Сколько писем в «сто десять»? Это 17, или это 16? Было бы намного легче проверить свою работу, если бы вы приняли такую ​​стратегию:

 unit_names = """zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen""".split() tens_names = """zero ten twenty thirty forty fifty sixty seventy eighty ninety""".split() def english(n): "Return the English name for n, from 0 to 999999." if n >= 1000: thous = english(n // 1000) + " thousand" n = n % 1000 if n == 0: return thous elif n < 100: return thous + " and " + english(n) else: return thous + ", " + english(n) elif n >= 100: huns = unit_names[n // 100] + " hundred" n = n % 100 if n == 0: return huns else: return huns + " and " + english(n) elif n >= 20: tens = tens_names[n // 10] n = n % 10 if n == 0: return tens else: return tens + "-" + english(n) else: return unit_names[n] def letter_count(s): "Return the number of letters in the string s." import re return len(re.findall(r'[a-zA-Z]', s)) def euler17(): return sum(letter_count(english(i)) for i in range(1, 1001)) 

При таком подходе легче проверить результат:

 >>> english(967) 'nine hundred and sixty-seven' 
  • Индекс элементов дубликатов в списке python
  • PEP8: линия продолжения с отступом для визуального отступа
  • dict.fromkeys указывают на один и тот же список
  • Новичок задается вопросом, является ли его код «Pythonic»
  • Пакет номеров Python?
  • Какие интересные хаки можно сделать с помощью sys.settrace?
  • как пройти через dict?
  • Цифровой корень без петель Python
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.