0votos

Crear la tabla de contenido de un libro en Haskell

por josejuan hace 5 años

Recursivamente agrupando por índice inicial menor.

Alguien ha perdido los números de índice de cada contenido de un libro ¿serás capaz de reconstruirlo?.

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
{- 
 
   Puede resolverse recursivamente, teniendo en cuenta que la cadena 
   se "parte" en trozos que comienzan en el menor de los niveles, por 
   ejemplo, supongamos que el primer nivel es el 1, entonces, si los 
   demás niveles los representamos por un *, una cadena como 
 
          1*******1**11******1***** 
 
   quedaría dividida en las ramas "iguales" (hijos del nivel anterior) como 
 
          1*******  1**  1  1******  1***** 
 
   y aplicaríamos el mismo procedimiento (recursivamente) a las colas de cada 
   una de estas cadenas en el siguiente nivel, por ejemplo, si es 
 
          12332234  1**  1  1******  1***** 
 
   aplicar el mismo procedimiento a la cola del primer trozo es hacerlo a 
 
          2332234 
 
   que quedaría dividido (usando el mismo procedimiento de antes) como 
 
          233 2 234 
 
   y así sucesivamente. 
 
-} 
 
-- Nuestro árbol es un título con otro árbol como hijo 
data Tree a = Tree a [Tree a] deriving Show 
 
-- Pasar la lista a árbol, es aplicar el procedimiento indicado 
listToTree = map (\((t, _):xs) -> Tree t $ listToTree xs) . groupBy ((.snd).(<).snd) 
 
-- Y ya está. 
 
 
 
 
 
 
-- Por ejemplo, si tenemos la lista indicada en el enunciado del desafío 
apartados = [ ( "Introducción", 1::Int ) 
            , ( "Motivación", 2 ) 
            , ( "Reseña histórica", 2 ) 
            , ( "Origen", 3 ) 
            , ( "Trabajos preliminares", 3 ) 
            , ( "Soluciones actuales", 2 ) 
            , ( "Objetivo de este libro", 2 ) 
            , ( "Requisitos", 1 ) 
            , ( "Hardware", 2 ) 
            , ( "Software", 2 ) 
 
-- Al pasarlo a árbol obtenemos 
{- 
*Main> listToTree apartados 
  [ Tree "Introducción" 
         [ Tree "Motivación" [] 
         , Tree "Reseña histórica" 
                [ Tree "Origen" [] 
                , Tree "Trabajos preliminares" [] 
         , Tree "Soluciones actuales" [] 
         , Tree "Objetivo de este libro" [] 
  , Tree "Requisitos" 
         [ Tree "Hardware" [] 
         , Tree "Software" [] 
-} 
 
 
 
-- Si adicionalmente se quiere implementar (en el desafío se supone ya dada) la función 
-- que enumera la tabla de contenido 
contentTable xs = do 
  (Tree t c, ns) <- zip xs $ [show n ++ "." | n <- [1..]] 
  ((ns ++ " " ++ t): (map (ns ++) $ contentTable c)) 
 
-- Por ejemplo: 
{- 
*Main> mapM_ putStrLn $ contentTable $ listToTree apartados 
    1. Introducción 
    1.1. Motivación 
    1.2. Reseña histórica 
    1.2.1. Origen 
    1.2.2. Trabajos preliminares 
    1.3. Soluciones actuales 
    1.4. Objetivo de este libro 
    2. Requisitos 
    2.1. Hardware 
    2.2. Software 
-} 
 
 
-- Si además se quieren poner tabuladores en cada nivel 
withTabs xs = [(take ((4*) $ ((-1)+) $ length $ filter (=='.') $ takeWhile (/=' ') t) $ repeat ' ') ++ t | t <- xs] 
 
-- Por ejemplo: 
{- 
*Main> mapM_ putStrLn $ withTabs $ contentTable $ listToTree apartados 
    1. Introducción 
        1.1. Motivación 
        1.2. Reseña histórica 
            1.2.1. Origen 
            1.2.2. Trabajos preliminares 
        1.3. Soluciones actuales 
        1.4. Objetivo de este libro 
    2. Requisitos 
        2.1. Hardware 
        2.2. Software 
-} 

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.