Files
exercism/python/say/say.py
2019-07-17 14:35:25 -05:00

60 lines
1.5 KiB
Python

sub = {
1_000_000_000_000 : 'trillion',
1_000_000_000 : 'billion',
1_000_000 : 'million',
1000 : 'thousand',
100 : 'hundred',
90 : 'ninety',
80 : 'eighty',
70 : 'seventy',
60 : 'sixty',
50 : 'fifty',
40 : 'forty',
30 : 'thirty',
20 : 'twenty',
}
number = {
12 : 'twelve',
11 : 'eleven',
10 : 'ten',
9 : 'nine',
8 : 'eight',
7 : 'seven',
6 : 'six',
5 : 'five',
4 : 'four',
3 : 'three',
2 : 'two',
1 : 'one',
0 : 'zero'
}
teen = {i + 10 : number[i] + 'teen' for i in range(3, 10)}
teen[13] = 'thirteen';teen[15] = 'fifteen';teen[18] = 'eighteen'
def say(n):
if n < 0:
raise ValueError(f'Cannot parse negative number \'{n}\'')
# return 'negative ' + say(abs(n))
elif n < 13:
return number[n]
elif n < 20:
return teen[n]
elif n < 100:
return sub[n // 10 * 10] + (('-' + number[n % 10]) if n % 10 != 0 else '')
elif max(*tuple(sub.keys()), n) == n:
raise ValueError(f'Cannot support large number \'{n}\'')
else:
res = []
while n > 0:
if n >= 100:
temp = max(sub.keys(), key=lambda item: 0 if item > n else item)
prefix = n // temp
n = n % temp
res.append(say(prefix) + ' ' + sub[temp])
else:
res.append(say(n))
n = 0
if len(res) < 2: return ' '.join(res)
return ' '.join(res[:-1]) + ' and ' + res[-1]