Menu Close

Matrices centro simétricas

Una matriz centro simétrica es una matriz cuadrada que es simétrica respecto de su centro. Por ejemplo, de las siguientes matrices, las dos primeras son simétricas y las otras no lo son

   (1 2)   (1 2 3)   (1 2 3)   (1 2 3)    
   (2 1)   (4 5 4)   (4 5 4)   (4 5 4)
           (3 2 1)   (3 2 2)

Definir la función

   esCentroSimetrica :: Eq t => Array (Int,Int) t -> Bool

tal que (esCentroSimetrica a) se verifica si la matriz a es centro simétrica. Por ejemplo,

   λ> esCentroSimetrica (listArray ((1,1),(2,2)) [1,2, 2,1])
   True
   λ> esCentroSimetrica (listArray ((1,1),(3,3)) [1,2,3, 4,5,4, 3,2,1])
   True
   λ> esCentroSimetrica (listArray ((1,1),(3,3)) [1,2,3, 4,5,4, 3,2,2])
   False
   λ> esCentroSimetrica (listArray ((1,1),(2,3)) [1,2,3, 4,5,4])
   False

Soluciones

import Data.Array 
 
esCentroSimetrica :: Eq t => Array (Int,Int) t -> Bool
esCentroSimetrica a =
  n == m && and [a!(i,j) == a!(n-i+1,n-j+1) | i <- [1..n], j <- [i..n]] 
  where (_,(n,m)) = bounds a
Inicial

7 soluciones de “Matrices centro simétricas

  1. alerodrod5
    import Data.Array
    type Vector a = Array Int a
    type Matriz a = Array (Int,Int) a
     
    esCentroSimetrica :: Eq t =>   Array (Int,Int) t -> Bool
    esCentroSimetrica a | esCuadrada a = and (map (iguales.reverseSegundo) (zip xs (reverse xs)))
                        | otherwise = False
      where xs = columnasMat a
     
    numFilas ::  Matriz a -> Int
    numFilas = fst . snd . bounds
     
    numColumnas ::  Matriz a -> Int 
    numColumnas = snd . snd . bounds
     
    esCuadrada :: Matriz a -> Bool
    esCuadrada x = numFilas x == numColumnas x
     
    columnasMat ::   Matriz a -> [[a]]
    columnasMat  p = [map snd [(i,p ! (i,x)) | i <- [1..n]] | x<-[1..n]]
      where n = numFilas p
     
    reverseSegundo :: ([a],[a]) -> ([a],[a])
    reverseSegundo (xs,ys) = (xs,reverse ys)
     
    iguales :: Eq a =>([a],[a]) -> Bool
    iguales (xs,ys) = xs==ys
  2. guigornun
     
    import Data.Array
     
    esCentroSimetrica :: Eq t => Array (Int,Int) t -> Bool
    esCentroSimetrica a | m == n = and [a ! (i,j) == a ! (m-(i-1), m-(j-1)) | (i,j) <- mitadSuperior]
                        | otherwise = False
                          where (m,n) = (numFilas a, numCols a)
                                mitadSuperior = filter ((<=k).fst) (range ((1,1),(m,n)))
                                k = ceiling ((fromIntegral n)/2)
                                numFilas = fst . snd . bounds
                                numCols = snd . snd . bounds
  3. albcarcas1
     
    import Data.Array
     
    esCentroSimetrica :: Eq t => Array (Int,Int) t -> Bool
    esCentroSimetrica = aux . elems
      where aux xs | even (length xs) = take n xs == reverse(drop n xs)
                   | otherwise        = take n xs == reverse(drop (n+1) xs)
               where n = floor((genericLength xs)/2)
  4. angruicam1
    import Data.Array (Array, listArray, (!), bounds)
     
    esCentroSimetrica :: Eq t => Array (Int,Int) t -> Bool
    esCentroSimetrica a
      | odd m     =
        p && and [a!(i,j) == a!(i',j')
                 | i <- [1..m], j <- [1..n`div`2+1],
                   let i' = m+1-i, let j' = n+1-j]
      | otherwise =
        p && and [a!(i,j) == a!(i',j')
                 | i <- [1..m], j <- [1..n`div`2],
                   let i' = 2*((m+1)`div`2)+1-i,
                   let j' = 2*((n+1)`div`2)+1-j]
      where (_,(m,n)) = bounds a
            p         = m == n
  5. josejuan

    Si nos fijamos en los “círculos concéntricos” que forma la matriz respecto del centro y para cada uno trazamos un diámetro cualquiera, los elementos inmediatos a cada lado deben ser opuestos (si en un lado del diámetros tenemos A|B en el opuesto debemos tener B|A) y ésto para cualquier diámetro y “círculo”. Ahora, cualquier transformación que preserve la simetría anterior, será válida para verificarla (la simetría). Si tomamos en zigzag los elementos, los “círculos” quedarán mezclados, pero preservan la simetría indicada antes.

    esCentroSimetrica :: Eq t => Array (Int, Int) t -> Bool
    esCentroSimetrica = and . ap (zipWith (==)) reverse . elems
    

    • josejuan

      (debí de poner algún carácter mal)

      esCentroSimetrica :: Eq t => Array (Int, Int) t -> Bool
      esCentroSimetrica = and . ap (zipWith (==)) reverse . elems
  6. agumaragu1
    import Data.Array
     
    esCentroSimetrica :: Eq t => Array (Int, Int) t -> Bool
    esCentroSimetrica p | noCuadrada = False
                        | otherwise = and [p!(i,j) == p!(n-i+1,n-j+1) | i <- [1..n], j <- [1..i]]
      where (n,m) = snd $ bounds p
            noCuadrada = n /= m

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.