Skip to content

Instantly share code, notes, and snippets.

@williamhogman
Created October 4, 2020 20:00
Show Gist options
  • Save williamhogman/54ecaf9aeab9d182ca70fc6b0e8094b0 to your computer and use it in GitHub Desktop.
Save williamhogman/54ecaf9aeab9d182ca70fc6b0e8094b0 to your computer and use it in GitHub Desktop.
from typing import Tuple, List
t = "teen"
y = "ty"
NUMBERS = ["zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thir" + t,
"four" + t, "fif" + t, "six" + t, "seven" + t,
"eigh" + t, "nine" + t, "twenty"]
TENS = ["thir" + y, "four" + y, "fif" + y, "six" +
y, "seven" + y, "eight" + y, "nine" + y]
WORDS = {
10 ** 6: "milion",
10 ** 3: "thousand",
10 ** 2: "hundred",
}
WORDS.update(((i + 3) * 10, x) for i, x in enumerate(TENS))
WORDS.update(enumerate(NUMBERS))
CARDINALITIES = list(WORDS.keys())
CARDINALITIES.sort(reverse=True)
IntPair = Tuple[int, int]
def format(n: int) -> List[IntPair]:
if n == 1:
return [(1, 1)]
rem = n
while rem > 0:
for i, c in enumerate(CARDINALITIES):
if rem >= c:
x, rem = divmod(rem, c)
yield (x, c)
break
def nested_format(x: int) -> List[Tuple[List[IntPair], int]]:
for item in format(x):
if isinstance(item, int):
yield item
else:
y, c = item
for (z, cz) in format(y):
yield from nested_format(z)
yield cz
yield c
def n_to_s(n: int) -> str:
if n == 0:
return "zero"
if n == 1:
return "one"
toks = list(WORDS[x] for x in nested_format(n))
if len(toks) == 1 and n > 99:
toks.insert(0, "one")
return "_".join(toks)
for x in range(1, 10 ** 6 + 1):
print(n_to_s(x).upper() + " = " + str(x))
@williamhogman
Copy link
Author

Type annotations are all goofed but I CBA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment