-- commonly used functions, types and etc module Common where import Data.List (findIndex, elemIndex) import GHC.IO (unsafePerformIO) import Control.DeepSeq (deepseq) import Data.Char (isSpace) type Pos = (Int, Int) addPos :: Pos -> Pos -> Pos addPos (x1, y1) (x2, y2) = (x1 + x2, y1 + y2) subPos :: Pos -> Pos -> Pos subPos (x1, y1) (x2, y2) = (x1 - x2, y1 - y2) taxicabDist :: Pos -> Pos -> Int taxicabDist (x1, y1) (x2, y2) = abs (x1 - x2) + abs (y1 - y2) taxicabDist3 :: Pos3 -> Pos3 -> Int taxicabDist3 (x1, y1, z1) (x2, y2, z2) = abs (x1 - x2) + abs (y1 - y2) + abs (z1 - z2) type Pos3 = (Int, Int, Int) add3 :: Pos3 -> Pos3 -> Pos3 add3 (x1, y1, z1) (x2, y2, z2) = (x1 + x2, y1 + y2, z1 + z2) type Grid a = [[a]] (!?) :: [a] -> Int -> Maybe a xs !? n | n < 0 = Nothing | otherwise = foldr (\x r k -> case k of 0 -> Just x _ -> r (k-1)) (const Nothing) xs n (!!!) :: Grid a -> Pos -> a (!!!) grid (x, y) = grid !! y !! x (!!?) :: Grid a -> Pos -> Maybe a (!!?) grid (x, y) = (grid !? y) >>= (!? x) findPos :: (Eq a) => a -> Grid a -> Maybe Pos findPos target grid = do y <- findIndex (target `elem`) grid x <- elemIndex target (grid !! y) Just (x, y) gridMap :: (a -> b) -> Grid a -> Grid b gridMap f = map (map f) gridWidth :: Grid a -> Int gridWidth = length . head gridHeight :: Grid a -> Int gridHeight = length {-# NOINLINE debug #-} debug :: Show a => a -> () debug = unsafePerformIO . print {-# NOINLINE debugS #-} debugS :: String -> () debugS = unsafePerformIO . putStrLn trace :: Show b => b -> a -> a trace s = deepseq (debug s) traceS :: String -> a -> a traceS s = deepseq (debugS s) count :: (a -> Bool) -> [a] -> Int count f = length . filter f trim :: String -> String trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace iterateN :: (a -> a) -> Int -> a -> a iterateN f n a = iterate f a !! n