domingo, 24 de febrero de 2013


vi = valor inicial.
cdu = ( unidad, decena, centena ). 
Number = Cadena de entrada ( contiene el numero que se va a leer )
l = longitud de la cadena de entrada 
i = posicion de cada digito comenzando desde la ultima posicion.   vi: l
d = digito ( cada uno de los digitos que se leen de la entrada ). 
u = undad.       vi : u = 1      u = u * 10,   ( unidad = 1, decena = 10 centena = 100 )  
v = vector ( almacena las cadenas de lectura ).     Unidad: V[ n ]          Decena: V[ 20 + p ] exceptuando [ 10 - 19 ] = V[ n ]                Centena: V[ 30 + p ]                                   Miles/millones/billones = V[ 40 + p ]
n = valor acumulativo cdu.      vi : n = 0       n = d * u + n
s = buffer auxiliar ( almacena la concatenacion de  cdu ).   s = c + d + u
z = buffer principal.  ( contiene la cadena completa de salida ).   z  = cdu + cdu + cdu ...
p = posicion ( calcula la posicion en el vector de cadenas de lectura )   vi: p = 0    decena: p = d - 2  centena: p = d - 1  Miles/Millones: p = {  miles = 0, millones = 1, billones = 2  }
=  cadena temporal.
j = contador de milesimas/millones/billones. vi: 0   Ejs: 123.873.984.930 :  j = 3,     1.983 :  j = 1
r = diferencia entre la longitud y la posicion del digito.     r = l - i 
----------------------------------------------------------------------------------------------------------------------





La lógica del algoritmo es empezar leyendo carácter a carácter de derecha a izquierda (cadena inversa), cada 3 dígitos almacenamos el buffer auxiliar  en el buffer principal, luego reiniciamos el buffer auxiliar y las operaciones (se reinicia todo excepto el buffer principal y contador de miles/millones/billones).


U: valor de la unidad, inicia en 1,    U =  U * 10 , { U = 1 = Unidad, U =10=Decena,  U=100=Centena}
Reiniciamos por cada 3 dígitos que se lean (CDU = Centena.Decena. Unidad)
Ej: leemos 7254
it 1: U = 1
it 2: U = 10
it 3: U = 100
Reiniciamos U = 1
it 4: U = 1
….
n: valor acumulativo, inicia en 0,   n = d * u + n  
Reiniciamos n  = 0 por cada 3 dígitos que se lean (CDU)
Ej: leemos 7254
it 1: [  d = 4, U = 1, n = 0  ] entonces  n = ( 4 * 1 + 0 )  =  4
it 2: [  d = 5, U = 10, n = 4  ] entonces  n = (5 * 10 + 4)  = 54
it 3: [  d = 2, U = 100, n = 54  ] entonces  n =( 2 * 100 + 54 )  = 254
Reiniciamos  n = 0
it 4: [  d = 7, U = 1, n = 0  ] entonces  n =( 7 * 1 + 0 )  = 7
Tomemos los valores de n  y u de arriba para cada iteración.
Unidades: posiciones en el vector [0 – 9] entonces  se accede de forma directa   V[n]
Ej: leemos 7254
it 1: [  d = 4, U = 1, n = 4  ] , V[4] = “cuatro”
it 2: …entra en decena
it 3: …entra en centena
Reiniciamos  n = 0, U = 1
it 4: [  d = 7, U = 1, n = 7 ],  V[7] = “siete”
Decenas: posiciones en el vector [20 – 27], entonces V [20 + p],  donde p = d – 2, si p < 0 entonces está en el rango     [10 - 19]  su valor se obtiene con V[n]  
Ej: leemos 7254
it 1: …entra en unidad
it 2: [  d = 5, U = 10, n = 54 ] entonces, p = ( 5 - 2) = 3,   V[23] = “cincuenta”,
Si el digito leído fuera 1 en lugar de 5, es decir fuera 7214,  entonces n = 14,  p = (1 - 2) = (-1)  < 0,  por tanto obtendríamos su valor directo con V [14] =”catorce” limpiaríamos el valor de la unidad que era “cuatro”.
it 3: …entra en centena
Reiniciamos  n = 0, U = 1
it 4: …entra en unidad
Centenas: posiciones en el vector [30 – 38], entonces V [30 + p],  donde p = d – 1
Ej: leemos 7254
it 1: …entra en unidad
it 2: …entra en decena
it 3: [  d = 2, U = 100, n = 254 ], p = (2 - 1) = 1,  V[31] = “doscientos”
Reiniciamos  n = 0, U = 1
it 4: …entra en unidad

Miles/millones/billones: V [40 + p], donde p = {0, 1 o 2},  si ( j > 2 ) entonces p = 2 sino p = j & 1,   r = l - i
( J & 1 ) devuelve 0 si j es par y 1 si es impar, ( 0  & 1) = 0,  (1 & 1) = 1, (2 & 1) = 0, (3 & 1) = 0 …
r es la diferencia entre l (longitud total de la cadena numérica de entrada ) e  i( índice del digito leído )
j es un valor  que inicia en 0 y  se incrementa siempre que encuentre una unidad Miles/millones/billones
Solo se calcula Miles/millones/billones si  r  > 0, verifica que hayan dígitos por leer  y si  r mod  3 = 0, es decir si se ha leído una (CDU), entonces si ambas condiciones se cumplen calculamos p  y  buscamos en el vector.
Ej: leemos 7254
it 1: [ j = 0, l = 4, i = 4 ] …entra en unidad  r = ( 4 – 4 ) =  0, verificamos  ( 0  > 0 ) No, ( 0 mod  3 = 0 )  Si
it 2: [ j = 0, l = 4, i = 3 ] …entra en decena r = ( 4 – 3 ) =  1, verificamos  ( 1  > 0 ) Si, ( 1 mod  3 = 0 )  No
it 3: [ j = 0, l = 4, i = 2] …entra en centena r = ( 4 – 2 ) =  2, verificamos  ( 2  > 0 ) Si, ( 2 mod  3 = 0 )  No
Reiniciamos  n = 0, U = 1
it 4: [ j = 0, l = 4, i = 1] …entra en unidad  r = ( 4 – 1 ) =  3, verificamos  ( 3  > 0 ) Si, ( 3 mod  3 = 0 )  Si
Se cumplen ambas condiciones entonces calculamos p, si  ( j = 0) > 2 No  entonces p = ( 0 & 1 ) = 0,
V[40  + 0 ] = “mil”


 Ej: para 2258, l = 4, entonces, iteración 1:  [i = 4, d = 8, u = 1, n = 0],  n = ( 8 * 1 + 0 ) = 8 , si u = 1, entonces accedemos a su valor en el vector directamente v [ n ], el valor será s = v[ 8 ] = "ocho", entonces n = 8, u = 10, s ="ocho", iteración 2:  [i = 3, d = 5, u = 10, n = 8],        n  = ( 5 * 10  + 8 ) = 58, si u = 10, entonces p = d – 2  es decir p = ( 5 – 2 ) = 3,  si p >= 0 y d <> 2 entonces  t = v[ 20 + p ] , t = V[ 23 ] = “cincuenta”, entonces n = 58, u = 100, s = (  t + “ y ” + s ) = “cincuenta y ocho”, si d = 2 si en el ejemplo fuera 1228 entonces seria , n = ( 2 * 10 + 8 ) = 28, p = ( 2 – 2 ) = 0,  t = v[ 20 ] = “veinte”,  s = ( “veinti” + s ) = “veintiocho” para esta iteración,   si p < 0 quiere decir que la unidad de decena esta entre [ 10 – 19 ] por lo cual accedemos directamente  v[ n ] , si en el ejemplo fuera 1218 entonces  en esta iteración el valor acumulativo seria n = ( 1 * 10 + 8 ) = 18 , p = ( 1 – 2 ) = (-1), por tanto obtendríamos t = v[ 18 ] = “dieciocho”, iteración 3: [i = 2, d = 2, u = 100, n = 58],  n = ( 2 * 100 + 58 ) = 258, si u = 100, entonces p = d – 1  es decir p = ( 2 – 1 ) = 1,  si d <> 1, entonces  t = v[ 30 + p ] , t = v[ 31 ] = “doscientos”, s = ( t + “ “ + s )  = “doscientos cincuenta y ocho”, si d = 1 si en el ejemplo fuera 1128 entonces seria  entonces p = ( 1 – 1 ) = 0,  t = v[ 30 + p ] + “to”,  t = ( v[30] + “to” ) =”ciento”, s = ( t + s ) = “ciento cincuenta y ocho”, como u  = 100 entonces reiniciamos todas las variables pero antes guardamos en el buffer principal (z) el buffer auxiliar = cdu (s), es decir z = s = “ciento cincuenta y ocho”, reiniciamos variables u = 1, s = ””, n = 0, repetimos los pasos anteriores iteración 4: [i = 1, d = 2, u = 1, n = 0] , aquí hacemos lo mismo que en la iteración 1,  n = ( 2 * 1 + 0 )  = 2 , si u = 1, si u = 1, entonces accedemos a su valor en el vector directamente v [ n ], el valor será s = v[ 2 ] = "dos", como hemos terminado de leer los caracteres terminamos las iteraciones.Este paso se hace en cada iteración, verifica los miles/millones/billones
j es un contador miles/millones/billones que inicia en 0 e incrementa siempre que  encuentra una unidad  de miles/millones/billones.
l es longitud de vector
i es el índice de posiciones de cada digito

1.    obtener la posición real,  r = l – i
2.    Verificar si hay más números por leer esto se verifica, r  >  0
3.    verificar  si es es miles/millones/billones,  r  mod  3 = 0
4.    si 2 y 3 se cumplen, calcular posición del vector, entonces
p = ( r > 10 ) ?  2 : j++ & 1;  
explico esta instrucción:

si r > 10, p = 2 es decir que son billones, si no es asi hago un and  a nivel de bits sobre j, este and (& ) lo que me devuelve es 0 si es par y 1 si es impar, Ej:
p = j & 1
para j = 0 :  p = ( 0 & 1 ) = 0 , j = 1 : p= (1 & 1) = 1 , j =2 :   p ( 2 & 1 ) = 0 …
5.    t = V[ 40 + p ]

para el ejemplo actual 2258, solo se cumplen las 2 condiciones en la iteracion 4: como i empieza en l, entonces parar it 1: i  = 4, it 2: i  = 3, it 3: i  = 2, it 4: i  = 1
iteracion 4: [l = 4, i = 0, j = 0, r  =  l – i ], entonces  r = ( 4  - 1 ) = 3,
r > 0  = si , r mod 3 = 0  = si, se cumplen ambas entonces,  r > 10 no cumple por tanto p = j++ & 1,  p = ( 0 & 1 ) = 0 , incrementa  j = 1, accedemos a vector t = v[40 + p], t = v[40] = “mil”, z = ( “ ” + t + “ ” + z )  = “ mil doscientos cincuenta y ocho”


Al salir del ciclo
Z =  ( s + z ) , como z = “ mil doscientos cincuenta y ocho” y s = “dos”, entonces z = “dos mil doscientos cincuenta y ocho”