Last active
January 17, 2020 09:45
-
-
Save josephlr/b109d17dfb69ba6311bc7c337eacd05d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
singles = { | |
0: "", # This is wrong for "zero", but is right for everything else. | |
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", | |
} | |
tens = { | |
2: "twenty", | |
3: "thirty", | |
4: "forty", | |
5: "fifty", | |
6: "sixty", | |
7: "seventy", | |
8: "eighty", | |
9: "ninety", | |
} | |
large = [ | |
(10**3, 10**2, "hundred"), | |
(10**6, 10**3, "thousand"), | |
(10**9, 10**6, "million"), | |
(10**12, 10**9, "billion"), | |
] | |
def word(n): | |
if n in singles: | |
return singles[n] | |
if n < 100: | |
d = n // 10 | |
r = n % 10 | |
return tens[d] + word(r) | |
for (limit, step, name) in large: | |
if n < limit: | |
d = n // step | |
r = n % step | |
return word(d) + name + word(r) | |
raise RuntimeError("Number %d out of range" % n) | |
def weight(n): | |
return sum(ord(c) - ord('a') + 1 for c in word(n)) | |
## Test cases | |
assert(weight(1) == 34) | |
assert(weight(2) == 58) | |
assert(weight(1417) == 379) | |
assert(weight(3140275) == 718) | |
# We need the overall delta to be positive | |
delta = lambda n : weight(n) - n | |
# Adding anything "two hundred" or greater is a net loss | |
for i in range(200, 10000, 100): | |
assert(delta(i) < 0) | |
# The loss from adding a "one thousand" (or anything higher) offsets any gain | |
# from lower numbers < 200. | |
min_loss = min([-delta(i) for i in range(1000,10000,1000)]) | |
max_gain = max([delta(i) for i in range(0, 200)]) | |
assert(min_loss > max_gain) | |
# Get the answer | |
i_max = 0 | |
for i in range(0,1000): | |
d = delta(i) | |
if d > 0: | |
i_max = i | |
print(i_max) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment