elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Programa que imprime un número entre 0 y un billón como texto [SWI-Prolog]
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Programa que imprime un número entre 0 y un billón como texto [SWI-Prolog]  (Leído 1,192 veces)
_TTFH_3500

Desconectado Desconectado

Mensajes: 122



Ver Perfil
Programa que imprime un número entre 0 y un billón como texto [SWI-Prolog]
« en: 8 Octubre 2020, 23:34 pm »

Siempre quise hacer un programa que dado un numero lo imprima como texto, por ejemplo 132 -> ciento treinta y dos, pero nunca me puse, hasta hoy que vi gramáticas de cláusulas definidas en programación lógica y en poco más de media hora salió.
Los casos más difíciles de hacer fueron por ejemplo 16 (dieciséis), 21 (veintiuno) que son una única palabra y 1002 (mil dos) que no es “un mil dos” o “uno mil dos”.
Como no chequeo que el resto sea distinto de cero pueden generarse casos como “40 -> cuarenta y cero” o “41 -> cuarenta y cero y uno, cuarenta y cero… y cero y uno” que son quitados con el operador cut (!).
Les dejo acá el código y algunos ejemplos.
17 diecisiete
29 veintinueve
547 quinientos cuarenta y siete
1234 mil doscientos treinta y cuatro
3597426 tres millones quinientos noventa y siete mil cuatrocientos veintiséis
742258963 setecientos cuarenta y dos millones doscientos cincuenta y ocho mil novecientos sesenta y tres
100000000000 cien mil millones
999999999999 novecientos noventa y nueve mil novecientos noventa y nueve millones novecientos noventa y nueve mil novecientos noventa y nueve
1000000000000 un billon
31000 treinta y uno mil*
* Y aquí encontré un bug, debería decir treinta y un mil

Código
  1. % Imprime un numero como texto
  2. print_number(N) :- numero(N, L, []), !, atomic_list_concat(L, ' ', A), writeln(A).
  3.  
  4. % Crea una lista [0..N]
  5. create_list(N, L) :- findall(X, between(0, N, X), L).
  6.  
  7. % Imprime los numeros entre 0 y N
  8. print_numbers(N) :- create_list(N, L), print_aux(L).
  9. print_aux([]).
  10. print_aux([X|L]) :- print_number(X), print_aux(L).
  11.  
  12. % Convierte un numero en una lista de palabras
  13. % ej: numero(132, L, []) -> [ciento, treinta, y, dos].
  14. numero(0) --> [cero].
  15. numero(1) --> [uno].
  16. numero(2) --> [dos].
  17. numero(3) --> [tres].
  18. numero(4) --> [cuatro].
  19. numero(5) --> [cinco].
  20. numero(6) --> [seis].
  21. numero(7) --> [siete].
  22. numero(8) --> [ocho].
  23. numero(9) --> [nueve].
  24.  
  25. numero(10) --> [dies].
  26. numero(11) --> [once].
  27. numero(12) --> [doce].
  28. numero(13) --> [trece].
  29. numero(14) --> [catorce].
  30. numero(15) --> [quince].
  31.  
  32. numero(20) --> [veinte].
  33. numero(30) --> [treinta].
  34. numero(40) --> [cuarenta].
  35. numero(50) --> [cincuenta].
  36. numero(60) --> [sesenta].
  37. numero(70) --> [setenta].
  38. numero(80) --> [ochenta].
  39. numero(90) --> [noventa].
  40. numero(100) --> [cien].
  41.  
  42. % Convertir numeros entre 16 y 19
  43. numero(N) --> {N > 15, N < 20, U is N mod 10, numero(U, X, []), atomic_list_concat([dieci|X], S)}, [S].
  44. % Convertir numeros entre 21 y 29
  45. numero(N) --> {N > 20, N < 30, U is N mod 10, numero(U, X, []), atomic_list_concat([veinti|X], S)}, [S].
  46. % Convertir numeros entre 31 y 99
  47. numero(N) --> {N > 30, N < 100, D is N - (N mod 10), U is N mod 10}, numero(D), [y], numero(U).
  48.  
  49. numero(200) --> [doscientos].
  50. numero(300) --> [trescientos].
  51. numero(400) --> [cuatrocientos].
  52. numero(500) --> [quinientos].
  53. numero(600) --> [seiscientos].
  54. numero(700) --> [setecientos].
  55. numero(800) --> [ochocientos].
  56. numero(900) --> [novecientos].
  57. numero(1000) --> [mil].
  58.  
  59. % Convertir numeros entre 101 y 199
  60. numero(N) --> {N > 100, N < 200, D is N mod 100}, [ciento], numero(D).
  61. % Convertir numeros entre 201 y 999
  62. numero(N) --> {N > 200, N < 1000, C is N - (N mod 100), D is N mod 100}, numero(C), numero(D).
  63.  
  64. % Convertir numeros entre 1001 y 1999
  65. numero(N) --> {N > 1000, N < 2000, D is N mod 1000}, [mil], numero(D).
  66. % Convertir numeros entre 2000 y 999 000 que terminan en 000, ej: 7000
  67. numero(N) --> {N >= 2000, N =< 999000, C is N div 1000, D is N mod 1000, D = 0}, numero(C), [mil].
  68. % Convertir numeros entre 2001 y 999 999
  69. numero(N) --> {N > 2000, N < 1000000, C is N div 1000, D is N mod 1000}, numero(C), [mil], numero(D).
  70.  
  71. numero(1000000) --> [un, millon].
  72.  
  73. % Convertir numeros entre 1 000 001 y 1 999 999
  74. numero(N) --> {N > 1000000, N < 2000000, D is N mod 1000000}, [un, millon], numero(D).
  75. % Convertir numeros entre 2 000 000 y 999 999 000 000 que terminan en 000 000, ej: 7 000 000
  76. numero(N) --> {N >= 2000000, N =< 999999000000, C is N div 1000000, D is N mod 1000000, D = 0}, numero(C), [millones].
  77. % Convertir numeros entre 2000001 y 999 999 999 999
  78. numero(N) --> {N > 2000000, N < 1000000000000, C is N div 1000000, D is N mod 1000000}, numero(C), [millones], numero(D).
  79.  
  80. numero(1000000000000) --> [un, billon].
  81.  

Para ejecutar instalan SWI-Prolog
Guardan el código como “numtext.pl”
Abren cmd en el directorio donde guardaron el archivo
> swipl numtext.pl
?- print_number(N). # donde N es el número a mostrar


En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines