module Search (word_exist) where

import Data.Array
import qualified Data.Set as SetDash

get_nbrs :: Int -> Int -> [(Int, Int)]
get_nbrs i j = [(i-1,j), (i,j+1), (i+1,j), (i,j-1), (i-1,j-1), (i+1,j+1),(i+1,j-1),(i-1,j+1)]

visit_cell :: Array (Int, Int) Char -> SetDash.Set(Int, Int) -> Int -> Int -> [Char] -> (Int,Int) -> Bool
visit_cell _ _ _ _ [] _  = True
visit_cell matrix visited m n (x:xs) (i,j) | i < 1 || i > m = False
                                         | j < 1 || j > n = False
                                         | SetDash.member (i,j) visited = False
                                         | x /= (matrix ! (i,j)) = False
                                         | otherwise = any (==True) children_visits
                                         where
                                            visited_dash = SetDash.insert (i,j) visited
                                            visit_cell_dash = visit_cell matrix visited_dash m n xs
                                            children_visits = map visit_cell_dash (get_nbrs i j)

word_exist :: Array (Int, Int) Char -> Int -> Int -> [Char] -> Bool
word_exist _ _ _ []     = True
word_exist matrix m n (x:xs) = any (==True) valid_visits
                             where
                                cells = [(i,j) | i <- [1..m], j <- [1..n]]
                                visit_cell_dash = visit_cell matrix SetDash.empty m n (x:xs)
                                valid_visits = map visit_cell_dash cells
