Los requisitos eran hacerlo en ingles (you know numbers to words) y hacerlo en ruby.
¿Qué lógica utilicé?
Bueno, tanto las unidades como las centenas utilizan los mismos nombres salvo que las centenas llevan incorporada la palabra hundred así que utilicé un arreglo para manejar estas dos posiciones, luego caí en cuenta que en inglés (¿también en español?) el proceso se repite cada tres dígitos, es decir procesar por ejemplo 123 y 123xxx (nada en particular las 3 x's solo me refiero a cuales quiera dígitos que usemos) da exactamente igual salvo que cada 3 dígitos toca ponerle un nombre (miles, millones, billones, etc) por lo que para esta parte también generé un arreglo con los nombres, y el último caso es que los nombres para las decenas dependen del valor de las unidades cuando la decena es 1, es decir para los dieces (¿cómo se dice esto en español?) once, doce, etc, así que creé 2 arreglos, uno para las decenas con dígito 1 y otro para las decenas con cualquier otro dígito.
Y bueno, esto es lo que salió:
En Gist para que lo copien, mejoren, etc:
This file contains hidden or 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
ones = ['', ' one', ' two', ' three', ' four', ' five', ' six', ' seven', ' eight', ' nine'] | |
teens = [' ten', ' eleven', ' twelve', ' thirteen', ' fourteen', ' fifteen', ' sixteen', ' seventeen', ' eighteen', ' nineteen'] | |
tens = ['', ' ten', ' twenty', ' thirty', ' forty', ' fifty', ' sixty', ' seventy', ' eighty', ' ninety'] | |
multiples = ['', ' thousand', ' million', ' billion', ' trillion', ' quadrillion', ' quintillion', ' sextillion', ' septillion', ' octillion', ' nonillion', ' decillion'] | |
numbers = 0..1000 #Numbers can be a range (0..1000) or an array ([1, 532, 9843, 1943023]) | |
numbers.each do |number| | |
position = 0 | |
letters = number > 0 ? "" : "zero" | |
multiple = 0 | |
while (number > 0) do | |
letters = multiples[position] + letters #Set thousand, million, etc | |
position += 1 | |
#Only manage 3 digits at time (since process is repetitive). | |
#Also reversing the number allows as to handle numbers minor to 100 without any special case | |
digits = (number % 1000).to_s.split(//).reverse.map(&:to_i) | |
digits.each_with_index do |d, p| | |
letters = " hundred" + letters if p == 2 | |
next if p == 0 && digits[1] == 1 #if penultimate digit equals to 1 then last digit (in our array first digit) should not be printed | |
letters = teens[digits[0]] + letters and next if p == 1 and d == 1 | |
letters = tens[d] + letters if p == 1 | |
letters = ones[d] + letters if p != 1 | |
end | |
number /= 1000 #Discard used digits | |
end | |
p letters | |
end | |
No hay comentarios.:
Publicar un comentario