Skip to content

Instantly share code, notes, and snippets.

@ThatCoolCoder
Last active June 25, 2022 08:15
Show Gist options
  • Save ThatCoolCoder/535826d83c00600590ce563f4fff4be2 to your computer and use it in GitHub Desktop.
Save ThatCoolCoder/535826d83c00600590ce563f4fff4be2 to your computer and use it in GitHub Desktop.
Indonesian number converter, eg 123 -> seratus dua puluh tiga. Works up to 10^100 - 1. Created out of boredeom. Maybe I should port it to JS.
ZERO = 'nol'
ONE_SHORTHAND = 'se'
TEN = 'puluh'
TEEN = 'belas'
HUNDRED = 'ratus'
DIGIT_TO_WORD = {
'1' : 'satu',
'2' : 'dua',
'3' : 'tiga',
'4' : 'empat',
'5' : 'lima',
'6' : 'enam',
'7' : 'tujuh',
'8' : 'delapan',
'9' : 'sembilan',
}
GROUP_NAMES = ['ribu', 'juta', 'miliar', 'triliun',
# sorry folks, google translate only goes up to 10^12 so had to make my own up
'kuadriliun', 'kuintiliun',
'sextiliun', 'septiliun', 'oktiliun', 'noniliun', 'desiliun', 'undesiliun', 'duodesiliun', 'tredesiliun', 'kuatordesiliun', 'kuindesiliun',
'sexdesiliun', 'septendesiliun', 'oktodesiliun', 'novemdesiliun', 'vingtiliun',
'unvingtiliun', 'duovingtiliun', 'trevingtiliun', 'kuatorvingtiliun', 'kuinvingtiliun',
'sexvingtiliun', 'septenvingtiliun', 'oktovingtiliun', 'novemvingtiliun', 'trigintiliun',
'unatrigintiliun', 'duotrigintiliun']
def number_to_words(number: int) -> str:
if number == 0:
return ZERO
number_str = str(number)[::-1]
chunks = list(create_chunks(number_str, 3))
result = ''
for idx, group in enumerate(chunks):
group = group[::-1]
if group == '000':
continue
group_idx = idx - 1
if len(GROUP_NAMES) - 1 < group_idx:
raise Exception(f'Error: ran out of group names (highest is \'{GROUP_NAMES[-1]}\', equal to 10^{3 * (group_idx)})')
group_result = group_to_words(group)
if group_idx >= 0:
if group_result == DIGIT_TO_WORD['1']:
group_result = ONE_SHORTHAND + GROUP_NAMES[group_idx]
else:
group_result = group_result + ' ' + GROUP_NAMES[group_idx]
result = group_result + ' ' + result
result = result.strip()
return result
def group_to_words(group: str):
''' Like set multiplier but for a whole group '''
result = ''
if len(group) >= 3 and group[-3] != '0':
result += set_multiplier(group[-3], HUNDRED) + ' '
if len(group) >= 2 and group[-2] != '0':
is_teen = group[-2] == '1' and group[-1] != '0'
if is_teen:
result += set_multiplier(group[-1], TEEN) + ' '
else:
result += set_multiplier(group[-2], TEN) + ' '
if len(group) >= 1 and group[-1] != '0' and (len(group) == 1 or group[-2] != '1'):
result += DIGIT_TO_WORD[group[-1]] + ' '
result = result.strip()
return result
def set_multiplier(digit: str, suffix: str) -> str:
''' Turns (2, puluh) into (dua puluh) '''
if digit == '1':
return ONE_SHORTHAND + suffix
else:
return DIGIT_TO_WORD[digit] + ' ' + suffix
def create_chunks(data, n: int):
n = max(1, n)
return (data[i:i+n] for i in range(0, len(data), n))
if __name__ == '__main__':
user_input = int(input('Enter a number to convert: '))
print(number_to_words(user_input))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment