Ordenación de estructuras
Las notas de los dos primeros exámenes se pueden representar mediante el siguiente tipo de dato
1 2 |
data Notas = Notas String Int Int deriving (Read, Show, Eq) |
Por ejemplo, (Notas «Juan» 6 5) representa las notas de un alumno cuyo nombre es Juan, la nota del primer examen es 6 y la del segundo es 5.
Definir la función
1 |
ordenadas :: [Notas] -> [Notas] |
tal que (ordenadas ns) es la lista de las notas ns ordenadas considerando primero la nota del examen 2, a continuación la del examen 1 y finalmente el nombre. Por ejemplo,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
λ> ordenadas [Notas "Juan" 6 5, Notas "Luis" 3 7] [Notas "Juan" 6 5,Notas "Luis" 3 7] λ> ordenadas [Notas "Juan" 6 5, Notas "Luis" 3 4] [Notas "Luis" 3 4,Notas "Juan" 6 5] λ> ordenadas [Notas "Juan" 6 5, Notas "Luis" 7 4] [Notas "Luis" 7 4,Notas "Juan" 6 5] λ> ordenadas [Notas "Juan" 6 4, Notas "Luis" 7 4] [Notas "Juan" 6 4,Notas "Luis" 7 4] λ> ordenadas [Notas "Juan" 6 4, Notas "Luis" 5 4] [Notas "Luis" 5 4,Notas "Juan" 6 4] λ> ordenadas [Notas "Juan" 5 4, Notas "Luis" 5 4] [Notas "Juan" 5 4,Notas "Luis" 5 4] λ> ordenadas [Notas "Juan" 5 4, Notas "Eva" 5 4] [Notas "Eva" 5 4,Notas "Juan" 5 4] |
Soluciones
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 |
import Data.List (sort, sortBy) import Test.QuickCheck data Notas = Notas String Int Int deriving (Read, Show, Eq) -- 1ª solución ordenadas1 :: [Notas] -> [Notas] ordenadas1 ns = [Notas n x y | (y,x,n) <- sort [(y1,x1,n1) | (Notas n1 x1 y1) <- ns]] -- 2ª solución ordenadas2 :: [Notas] -> [Notas] ordenadas2 ns = map (\(y,x,n) -> Notas n x y) (sort [(y1,x1,n1) | (Notas n1 x1 y1) <- ns]) -- 3ª solución ordenadas3 :: [Notas] -> [Notas] ordenadas3 ns = sortBy (\(Notas n1 x1 y1) (Notas n2 x2 y2) -> compare (y1,x1,n1) (y2,x2,n2)) ns -- 4ª solución -- =========== instance Ord Notas where Notas n1 x1 y1 <= Notas n2 x2 y2 = (y1,x1,n1) <= (y2,x2,n2) ordenadas4 :: [Notas] -> [Notas] ordenadas4 = sort -- Comprobación de equivalencia -- ============================ -- notasArbitraria es un generador aleatorio de notas. Por ejemplo, -- λ> sample notasArbitraria -- Notas "achjkqruvxy" 3 3 -- Notas "abfgikmptuvy" 10 10 -- Notas "degjmptvwx" 7 9 -- Notas "cdefghjmnoqrsuw" 0 9 -- Notas "bcdfikmstuxz" 1 8 -- Notas "abcdhkopqsvwx" 10 7 -- Notas "abghiklnoqstvwx" 0 0 -- Notas "abfghklmnoptuvx" 4 9 -- Notas "bdehjkmpqsxyz" 0 4 -- Notas "afghijmopsvwz" 3 7 -- Notas "bdefghjklnoqx" 2 3 notasArbitraria :: Gen Notas notasArbitraria = do n <- sublistOf ['a'..'z'] x <- chooseInt (0, 10) y <- chooseInt (0, 10) return (Notas n x y) -- Notas es una subclase de Arbitrary instance Arbitrary Notas where arbitrary = notasArbitraria -- La propiedad es prop_ordenadas :: [Notas] -> Bool prop_ordenadas ns = all (== ordenadas1 ns) [f ns | f <- [ordenadas2, ordenadas3, ordenadas4]] -- La comprobación es -- λ> quickCheck prop_ordenadas -- +++ OK, passed 100 tests. |
El código se encuentra en GitHub.
La elaboración de las soluciones se muestra en el siguiente vídeo