Project Euler 17: (Iron)Python

Posted by Ben Griswold on Johnny Coder See other posts from Johnny Coder or by Ben Griswold
Published on Wed, 22 Sep 2010 20:24:53 +0000 Indexed on 2010/12/06 16:59 UTC
Read the original article Hit count: 367

In my attempt to learn (Iron)Python out in the open, here’s my solution for Project Euler Problem 17

As always, any feedback is welcome.

# Euler 17
# http://projecteuler.net/index.php?section=problems&id=17
# 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.
# If all the numbers from 1 to 1000 (one thousand)
# inclusive were written out in words, how many letters
# would be used?
#
# 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. The
# use of "and" when writing out numbers is in compliance
# with British usage.
import time
start = time.time()

def to_word(n):
    h = { 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", 1000 : "thousand" }

    word = ""

    # Reverse the numbers so position (ones, tens,
    # hundreds,...) can be easily determined
    a = [int(x) for x in str(n)[::-1]]

    # Thousands position
    if (len(a) == 4 and a[3] != 0):
        # This can only be one thousand based
        # on the problem/method constraints
        word = h[a[3]] + " thousand "

    # Hundreds position
    if (len(a) >= 3 and a[2] != 0):
        word += h[a[2]] + " hundred"

        # Add "and" string if the tens or ones
        # position is occupied with a non-zero value.
        # Note: routine is broken up this way for [my] clarity.
        if (len(a) >= 2 and a[1] != 0):
            # catch 10 - 99
            word += " and"
        elif len(a) >= 1 and a[0] != 0:
            # catch 1 - 9
            word += " and"

    # Tens and ones position
    tens_position_value = 99
    if (len(a) >= 2 and a[1] != 0):
        # Calculate the tens position value per the
        # first and second element in array
        # e.g. (8 * 10) + 1 = 81
        tens_position_value = int(a[1]) * 10 + a[0]

        if tens_position_value <= 20:
            # If the tens position value is 20 or less
            # there's an entry in the hash. Use it and there's
            # no need to consider the ones position
            word += " " + h[tens_position_value]
        else:
            # Determine the tens position word by
            # dividing by 10 first. E.g. 8 * 10 = h[80]
            # We will pick up the ones position word later in
            # the next part of the routine
            word += " " + h[(a[1] * 10)]

    if (len(a) >= 1 and a[0] != 0 and tens_position_value > 20):
        # Deal with ones position where tens position is
        # greater than 20 or we have a single digit number
        word += " " + h[a[0]]

    # Trim the empty spaces off both ends of the string
    return word.replace(" ","")    

def to_word_length(n):
    return len(to_word(n))    

print sum([to_word_length(i) for i in xrange(1,1001)])

print "Elapsed Time:", (time.time() - start) * 1000, "millisecs"
a=raw_input('Press return to continue')

© Johnny Coder or respective owner

Related posts about ironpython

Related posts about languages