0votos

Dado un número entero no negativo mostrar su representación en español en Haskell

por josejuan hace 5 años

Básicamente es ir tratando las excepciones.

Por ejemplo, dado el número "21437" deberá indicar "veintiun mil cuatrocientos treinta y siete".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import Data.List 
import System.Random 
 
pequeños = ["cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve", "diez" 
               , "once", "doce", "trece", "catorce", "quince"] 
 
decenas = ["treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa"] 
 
centenas = ["seis", "sete", "ocho", "nove"] 
 
llones = ["mi", "bi", "tri", "cuatri", "quinti", "sexti", "septi", "octi", "noni", "deci", "undeci"] 
 
diNúmero :: Integral a => a -> String 
diNúmero = número False 
 
número :: Integral a => Bool -> a -> String 
número un = nm 
  where nm :: Integral a => a -> String 
        nm n 
          | n < 16                       = fp d10 
          | n < 20                       = "dieci" ++ f6 d0 
          | n == 20                      = "veinte" 
          | n < 30                       = "veinti" ++ f6 d0 
          | n < 100 && d0 == 0           = decenas !! (d1 - 3) 
          | n < 100                      = decenas !! (d1 - 3) ++ " y " ++ nm d0 
          | n == 100                     = "cien" 
          | n < 200                      = "ciento " ++ nm d10 
          | n < 500 && d10 == 0          = fp d2 ++ "cientos" 
          | n < 500                      = fp d2 ++ "cientos " ++ nm d10 
          | n == 500                     = "quinientos" 
          | n < 600                      = "quinientos " ++ nm d10 
          | n < 1000 && d10 == 0         = centenas !! (d2 - 6) ++ "cientos" 
          | n < 1000                     = centenas !! (d2 - 6) ++ "cientos " ++ nm d10 
          | n == 1000                    = "mil" 
          | n < 2000                     = "mil " ++ nm d210 
          | n < 1000000 && d210 == 0     = numP d543 ++ " mil" 
          | n < 1000000                  = numP d543 ++ " mil " ++ nm d210 
          | otherwise                    = millones llones nm $ unfoldr (\x -> if x == 0 then Nothing else Just (mod x 1000000, div x 1000000)) n 
 
          where d0   = n `mod` 10 
                d1   = fromIntegral $ (n `div` 10) `mod` 10 
                d10  = fromIntegral $ n `mod` 100 
                d2   = fromIntegral $ (n `div` 100) `mod` 10 
                d210 = n `mod` 1000 
                d543 = (n `div` 1000) `mod` 1000 
                dm   = n `mod` 1000000 
                numP = número True 
                f6 6 = "séis" 
                f6 d = nm d 
                fp d = case (un, d) of 
                       (True,  1) -> "un" 
                       otherwise  -> pequeños !! d 
                millones _ _ (a:[]) = numP a 
                millones (m:ms) f (a:b:cs) = millones ms numP (b:cs) ++ 
                                            (case b of 
                                               1 -> " " ++ m ++ "llón" 
                                               0 -> "" 
                                               otherwise -> " " ++ m ++ "llones") ++ 
                                            (if a /= 0 then (" " ++ f a) else "") 

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.