Menu Close

Máximos locales de una matriz

Un elemento de una matriz es un máximo local si es mayor que todos sus vecinos. Por ejemplo, en la matriz

    [[1,0,0,8],
     [0,2,0,3],
     [0,0,0,5],
     [3,5,7,6],
     [1,2,3,4]]

los máximos locales son 8 (en la posición (1,4)), 2 (en la posición (2,2)) y 7 (en la posición (4,3)).

Definimos el tipo de las matrices, mediante

   type Matriz a = Array (Int,Int) Int

y el ejemplo anterior por

   ej1 :: Matriz Int
   ej1 = listArray ((1,1),(5,4)) (concat [[1,0,0,8],
                                          [0,2,0,3],
                                          [0,0,0,5],
                                          [3,5,7,6],
                                          [1,2,3,4]])

Definir la función

   maximosLocales :: Matriz Int -> [((Int,Int),Int)]

tal que (maximosLocales p) es la lista de las posiciones en las que hay un máximo local, con el valor correspondiente. Por ejemplo,

   maximosLocales ej1 == [((1,4),8),((2,2),2),((4,3),7)]

Soluciones

import Data.Array
 
type Matriz a = Array (Int,Int) a
 
ej1 :: Matriz Int
ej1 = listArray ((1,1),(5,4)) (concat [[1,0,0,8],
                                       [0,2,0,3],
                                       [0,0,0,5],
                                       [3,5,7,6],
                                       [1,2,3,4]])
 
maximosLocales :: Matriz Int -> [((Int,Int),Int)]
maximosLocales p = 
    [((i,j),p!(i,j)) | (i,j) <- indices p,
               and [p!(a,b) < p!(i,j) | (a,b) <- vecinos (i,j)]] 
    where (_,(m,n)) = bounds p
          vecinos (i,j) = [(a,b) | a <- [max 1 (i-1)..min m (i+1)],
                                   b <- [max 1 (j-1)..min n (j+1)],
                                   (a,b) /= (i,j)]

5 soluciones de “Máximos locales de una matriz

  1. josejuan
    import Data.Array
    import qualified Data.Array as A
    import qualified Data.Map as M
     
    maximosLocales :: Matriz Int -> [((Int,Int),Int)]
    maximosLocales a =
     
      M.elems                           -- aquellos ...
      $ M.mapMaybeWithKey condicion     -- ... que cumplen la condición ...
      $ M.fromListWith maximo dobleKeys -- ... seleccionando el máximo por clave
     
      where
        -- para cada clave, se selecciona aquella de mayor valor
        maximo a b = if snd a < snd b then b else a
     
        -- con la condición de que el máximo sea aquel con la misma clave
        condicion k e@(q, _) = if k == q then Just e else Nothing
     
        -- un valor ((x, y), v) será evaluado en cada clave (x + dx, y + dy)
        dobleKeys = [((x + dx, y + dy), (k, v)) | (k@(x, y), v) <- A.assocs a
                                                , dx <- [-1..1], dy <- [-1..1]]
  2. Jesús Navas Orozco
    import Data.Array
     
    type Matriz a = Array (Int,Int) Int
     
    maximosLocales :: Matriz Int -> [((Int,Int),Int)]
    maximosLocales p = [(k,p!k)| k <- indices p, all (< p!k) (vecinos p k)]
     
    vecinos :: Matriz Int -> (Int,Int) -> [Int]
    vecinos p (i,j) = [p!k| k<-xs,k/=(i,j)]
                where xs = filter (x-> inRange (bounds p) x) [(i+a,j+b)|a<-ys,b<-ys]
                      ys = [-1,0,1]
  3. M Miranda
    import Data.Array
    type Matriz a = Array (Int,Int) Int
     
    maximosLocales :: Matriz Int -> [((Int,Int),Int)]
    maximosLocales p = 
        [((i,j),k) | ((i,j),k) <- assocs p, all (<k) (vecinos p (i,j))]
        where vecinos p (i,j) = [p!(a,b) | a <- [i-1..i+1], 
                                           b <- [j-1..j+1],
                                           a `notElem` [0,n+1],
                                           b `notElem` [0,m+1],
                                           (a,b) /= (i,j)]
              (n,m) = snd $ bounds p
  4. josejuan
    import Data.Array
     
    type Matriz a = Array (Int,Int) Int
     
    maximosLocales :: Matriz Int -> [((Int, Int), Int)]
    maximosLocales=(w->[k|k@((x,y),n)<-w
                          ,null[1|((u,v),m)<-w,n<=m,elem(abs$x-u,abs$y-v)$zip[1,0,1][0,1,1]]]).assocs
  5. Pedro Martín Chávez
    import Data.Array
     
    type Matriz a = Array (Int,Int) Int
     
    maximosLocales :: Matriz Int -> [((Int,Int),Int)]
    maximosLocales p = [a | a <- assocs p, maximoLocal a]
        where maximoLocal ((i,j),k) =
                  k > maximum [p!(i+x,j+y) | x <- ns, 
                                             y <- ns, 
                                             not (x == 0 && y == 0),
                                             inRange (bounds p) (i+x,j+y)]
              ns = [-1,0,1]

Escribe tu solución

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