Skip to content

Instantly share code, notes, and snippets.

@elarex
Created January 24, 2014 07:32
Show Gist options
  • Save elarex/8593495 to your computer and use it in GitHub Desktop.
Save elarex/8593495 to your computer and use it in GitHub Desktop.
Converting integers to words
class NumberToWords
MAPPING = {
:eng => {
:ones => %W(zero one two three four five six seven eight nine),
:teens => %W(ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen),
:tens => %W(ten twenty thirty fourty fifty sixty seventy eighty ninety)
},
:afr => {
:ones => %W(nul een twee drie vier vyf ses sewe agt nege),
:teens => %W(tien elf twaalf dertien veertien vyftien sestien sewentien agtien negentien),
:tens => %W(tien twintig dertig veertig vyftig sestig sewentig tagtig negentig)
}
}
def self.in_eng(number)
#force the integer
number = number.to_i
digits = number.to_s.length
result = []
teens = ((number < 20 && number >= 10) ? number%10 : 0)
if teens > 0
return MAPPING[:eng][:teens][teens%10] #word controlled by least significant digit
end
ones = number%10 ; number = (number/10)*10
tens = (number%100)/10 ; number = (number/100)*100
hundreds = (number%1000)/100 ; number = (number/1000)*1000
thousands = (number%1000000)/1000 ; number = (number/1000000)*1000000
millions = (number/1000000)
if millions > 0
result << "#{number_to_words_in_eng(millions)} million"
end
if thousands > 0
result << "#{number_to_words_in_eng(thousands)} thousand"
end
if hundreds > 0
result << "#{number_to_words_in_eng(hundreds)} hundred"
end
if tens > 0
result << "and" if digits > 2
result << MAPPING[:eng][:tens][(tens)-1] #word controlled by most significant digit
end
if ones > 0
result << MAPPING[:eng][:ones][ones]
end
if ones == 0 and digits == 1
result << MAPPING[:eng][:ones][ones]
end
result.join(' ')
end
def self.in_afr(number)
#force the integer
number = number.to_i
digits = number.to_s.length
result = []
teens = ((number < 20 && number >= 10) ? number%10 : 0)
if teens > 0
return MAPPING[:afr][:teens][teens%10] #word controlled by least significant digit
end
ones = number%10 ; number = (number/10)*10
tens = (number%100)/10 ; number = (number/100)*100
hundreds = (number%1000)/100 ; number = (number/1000)*1000
thousands = (number%1000000)/1000 ; number = (number/1000000)*1000000
millions = (number/1000000)
if millions > 0
result << "#{number_to_words_in_afr(millions)} miljoen"
end
if thousands > 0
result << "#{number_to_words_in_afr(thousands)} duisend"
end
if hundreds > 0
result << "#{number_to_words_in_afr(hundreds)} honderd"
end
if tens > 0
if ones > 0
result << MAPPING[:afr][:ones][ones]
result << "en"
end
result << MAPPING[:afr][:tens][(tens)-1] #word controlled by most significant digit
elsif ones > 0
result << MAPPING[:afr][:ones][ones]
end
if ones == 0 and digits == 1
result << MAPPING[:eng][:ones][ones]
end
result.join(' ')
end
end
@elarex
Copy link
Author

elarex commented Jan 24, 2014

This is needs to still be refactored, there is a lot of common code in the two worker methods. Also would be nice to extend the numeric class with this instead of having to call it explicitly.

@elarex
Copy link
Author

elarex commented Jan 24, 2014

I tries gems that do this, but they are severely complicated and over-engineered, adding Afrikaans was a massive pain. I only needed a very specific subset or translations (no ordinals of fractions, for example), so rolling my own made sense.

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