Last active
June 25, 2022 08:15
-
-
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.
This file contains 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
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