Ampliación de matrices por columnas
Las matrices enteras se pueden representar mediante tablas con índices enteros:
1 |
type Matriz = Array (Int,Int) Int |
Definir la función
1 |
ampliaColumnas :: Matriz -> Matriz -> Matriz |
tal que (ampliaColumnas p q) es la matriz construida añadiendo las columnas de la matriz q a continuación de las de p (se supone que tienen el mismo número de filas). Por ejemplo, si p y q representa las dos primeras matrices, entonces (ampliaColumnas p q) es la tercera
1 2 |
|0 1| |4 5 6| |0 1 4 5 6| |2 3| |7 8 9| |2 3 7 8 9| |
En Haskell, se definen las dos primeras matrices se definen por
1 2 |
ej1 = listArray ((1,1),(2,2)) [0..3] ej2 = listArray ((1,1),(2,3)) [4..9] |
y el cálculo de la tercera es
1 2 3 4 5 |
λ> ampliaColumnas ej1 ej2 array ((1,1),(2,5)) [((1,1),0),((1,2),1),((1,3),4),((1,4),5),((1,5),6), ((2,1),2),((2,2),3),((2,3),7),((2,4),8),((2,5),9)] λ> elems (ampliaColumnas ej1 ej2) [0,1,4,5,6,2,3,7,8,9] |
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
import Data.Array (Array, (!), array, bounds, elems, listArray) import Data.Matrix (Matrix, (<|>), fromList, ncols, nrows, toList) import Test.QuickCheck type Matriz = Array (Int,Int) Int ej1, ej2 :: Matriz ej1 = listArray ((1,1),(2,2)) [0..3] ej2 = listArray ((1,1),(2,3)) [4..9] -- 1ª solución -- =========== ampliaColumnas1 :: Matriz -> Matriz -> Matriz ampliaColumnas1 p1 p2 = array ((1,1),(m,n1+n2)) [((i,j), f i j) | i <- [1..m], j <- [1..n1+n2]] where ((_,_),(m,n1)) = bounds p1 ((_,_),(_,n2)) = bounds p2 f i j | j <= n1 = p1!(i,j) | otherwise = p2!(i,j-n1) -- 2ª solución -- =========== ampliaColumnas2 :: Matriz -> Matriz -> Matriz ampliaColumnas2 p1 p2 = matriz (matrix p1 <|> matrix p2) -- (matrix p) es la matriz p en el formatao de Data.Matrix. Por ejemplo, -- λ> ej1 -- array ((1,1),(2,2)) [((1,1),0),((1,2),1),((2,1),2),((2,2),3)] -- λ> matrix ej1 -- ┌ ┐ -- │ 0 1 │ -- │ 2 3 │ -- └ ┘ -- λ> matrix (ampliaColumnas1 ej1 ej2) -- ┌ ┐ -- │ 0 1 4 5 6 │ -- │ 2 3 7 8 9 │ -- └ ┘ matrix :: Matriz -> Matrix Int matrix p = fromList m n (elems p) where (_,(m,n)) = bounds p -- (matriz p) es la matriz p en el formato de Data.Array. Por ejemplo, -- λ> matriz (fromList 2 3 [1..]) -- array ((1,1),(2,3)) [((1,1),1),((1,2),2),((1,3),3),((2,1),4),((2,2),5),((2,3),6)] matriz :: Matrix Int -> Matriz matriz p = listArray ((1,1),(nrows p,ncols p)) (toList p) -- Comprobación de equivalencia -- ============================ data ParMatrices = P Matriz Matriz deriving Show -- parMatricesArbitrario es un generador de pares de matrices con el -- mismo número de filas. parMatricesArbitrario :: Gen ParMatrices parMatricesArbitrario = do m <- arbitrary `suchThat` (> 0) n1 <- arbitrary `suchThat` (> 0) n2 <- arbitrary `suchThat` (> 0) xs <- vector (m * n1) ys <- vector (m * n2) return (P (listArray ((1,1),(m,n1)) xs) (listArray ((1,1),(m,n2)) ys)) -- ParMatrices es una subclase de Arbitrary instance Arbitrary ParMatrices where arbitrary = parMatricesArbitrario -- La propiedad es prop_ampliaColumna :: ParMatrices -> Bool prop_ampliaColumna (P p q) = ampliaColumnas1 p q == ampliaColumnas2 p q -- La comprobación es -- λ> quickCheck prop_ampliaColumna -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> let p = listArray ((1,1),(10^3,10^3)) [1..] in maximum (ampliaColumnas1 p p) -- 1000000 -- (2.04 secs, 1,562,652,704 bytes) -- λ> let p = listArray ((1,1),(10^3,10^3)) [1..] in maximum (ampliaColumnas2 p p) -- 1000000 -- (0.69 secs, 738,508,624 bytes) |
El código se encuentra en GitHub.
La elaboración de las soluciones se describe en el siguiente vídeo
Nuevas soluciones
- En los comentarios se pueden escribir nuevas soluciones.
- El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>