Skip to content

Instantly share code, notes, and snippets.

@josephlr
Last active January 17, 2020 09:45
Show Gist options
  • Save josephlr/b109d17dfb69ba6311bc7c337eacd05d to your computer and use it in GitHub Desktop.
Save josephlr/b109d17dfb69ba6311bc7c337eacd05d to your computer and use it in GitHub Desktop.
#!/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