-
Notifications
You must be signed in to change notification settings - Fork 0
/
euler_017.py
117 lines (101 loc) · 2.6 KB
/
euler_017.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"""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?
"""
ONES = ['',
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
'eleven',
'twelve',
'thirteen',
'fourteen',
'fifteen',
'sixteen',
'seventeen',
'eighteen',
'nineteen']
TENS = ['',
'',
'twenty',
'thirty',
'forty',
'fifty',
'sixty',
'seventy',
'eighty',
'ninety']
TRIPLETS = ['',
'thousand',
'million',
'billion',
'trillion',
'quadrillion',
'quintillion',
'sextillion',
'septillion']
def tripled_digits(num):
"""Splits num into a list of at most three digits each, starting from
the right
"""
digits = map(int, str(num))
triples = []
triple = []
for digit in reversed(digits):
triple.insert(0,digit)
if len(triple) == 3:
triples.append(triple)
triple = []
if triple:
triples.append(triple)
return triples
def digits_to_num(digits):
place = 0
num = 0
for digit in reversed(digits):
num += digit * 10**place
place += 1
return num
def build_tripled(digits):
""" builds numbers up to but not including 1000 into a word
"""
num = digits_to_num(digits)
ndigits = len(digits)
inwords = ''
for idx, digit in enumerate(digits):
place = ndigits - idx - 1
if place == 2:
if digit != 0:
inwords += ONES[digit]+'hundredand'
elif place == 1:
if digit == 1:
return inwords+ONES[num % 100]
else:
inwords += TENS[digit]
elif place == 0:
inwords += ONES[digit]
return (inwords if inwords[-3:] != 'and' else inwords[:-3])
def convert_to_word(num):
"""convert number to a word
e.g. 123-> onehundredandtwentythree
"""
triples = tripled_digits(num)
inwords = ''
for idx, triple in enumerate(triples):
if any(triple):
inwords = build_tripled(triple) + TRIPLETS[idx] + inwords
return inwords
def numletters(up_to_num=1000):
nletters = 0
for i in range(1, up_to_num+1):
nletters += len(convert_to_word(i))
return nletters