Project Euler 17

后端 未结 1 1089
-上瘾入骨i
-上瘾入骨i 2020-12-11 10:18

I\'ve been trying to solve Euler 17 and have been running into some trouble. The definition of that problem is:

If the numbers 1 to 5 are written out

1条回答
  •  醉梦人生
    2020-12-11 10:54

    Explaining the discrepancy

    Your code is riddled with errors:

    1. This is wrong:

      maps[60] = 6
      

      Contribution to error: +100 (because it affects 60 to 69, 160 to 169, ..., 960 to 969).

    2. Several teenagers are mistaken:

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

      Contribution to error: +40 (because it affects 12, 13, ..., 112, 113, ..., 918)

    3. And any number of the form x10:

      >>> three_digit(110)
      17
      

      Contribution to error: 9 (because 110, 210, ... 910)

    4. The number 20 is not counted (you consider i < 20 and i > 20 but not i == 20).

      Contribution to error: −6

    5. The number 1000 is written "one thousand" in English but:

      >>> thousand(1000)
      8
      

      Contribution to error: −3

    6. You subtract 10 at the end in an attempt to compensate for one of these errors.

      Contribution to error: −10

    Total error: 100 + 40 + 9 − 6 − 3 − 10 = 130.

    How you could have avoided these mistakes

    By trying to work directly with letter counts you made it really hard for you to check your own work. How many letters are there in "one hundred and ten" again? Is it 17, or is it 16? It would have been much easier for you to test your work if you had adopted a strategy like this:

    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))
    

    With this approach it's easier to check your result:

    >>> english(967)
    'nine hundred and sixty-seven'
    

    0 讨论(0)
提交回复
热议问题