import Data.Matrix
type Campo = Matrix Int
type Casilla = (Int,Int)
ejCampo1, ejCampo2 :: Campo
ejCampo1 = fromLists [[9,0,0,0],
[0,0,0,0],
[0,9,0,0],
[0,0,0,0]]
ejCampo2 = fromLists [[9,9,0,0,0],
[0,0,0,0,0],
[0,9,0,0,0]]
-- 1ª solución
-- ===========
buscaminas1 :: Campo -> Campo
buscaminas1 c = matrix m n (\(i,j) -> minas c (i,j))
where m = nrows c
n = ncols c
-- (minas c (i,j)) es el número de minas en las casillas vecinas de la
-- (i,j) en el campo de mina c y es 9 si en (i,j) hay una mina. Por
-- ejemplo,
-- minas ejCampo (1,1) == 9
-- minas ejCampo (1,2) == 1
-- minas ejCampo (1,3) == 0
-- minas ejCampo (2,1) == 2
minas :: Campo -> Casilla -> Int
minas c (i,j)
| c!(i,j) == 9 = 9
| otherwise = length (filter (==9) [c!(x,y) | (x,y) <- vecinas m n (i,j)])
where m = nrows c
n = ncols c
-- (vecinas m n (i,j)) es la lista de las casillas vecinas de la (i,j) en
-- un campo de dimensiones mxn. Por ejemplo,
-- vecinas 4 (1,1) == [(1,2),(2,1),(2,2)]
-- vecinas 4 (1,2) == [(1,1),(1,3),(2,1),(2,2),(2,3)]
-- vecinas 4 (2,3) == [(1,2),(1,3),(1,4),(2,2),(2,4),(3,2),(3,3),(3,4)]
vecinas :: Int -> Int -> Casilla -> [Casilla]
vecinas m n (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)]
-- 2ª solución
-- ===========
buscaminas2 :: Campo -> Campo
buscaminas2 c = matrix m n (\(i,j) -> minas (i,j))
where m = nrows c
n = ncols c
minas :: Casilla -> Int
minas (i,j)
| c!(i,j) == 9 = 9
| otherwise =
length (filter (==9) [c!(x,y) | (x,y) <- vecinas (i,j)])
vecinas :: Casilla -> [Casilla]
vecinas (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)]