-
Notifications
You must be signed in to change notification settings - Fork 0
/
cavity-map.hs
76 lines (58 loc) · 1.48 KB
/
cavity-map.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module Main (main) where
import Control.Applicative
import Data.Array
import Data.Attoparsec.Text
import qualified Data.Scientific as S
import qualified Data.Text.IO as T
parseInteger :: (Integral a, Bounded a) => Parser a
parseInteger = do
mResult <- S.toBoundedInteger <$> scientific
case mResult of
Nothing ->
fail "Expected number"
Just result ->
return result
type Matrix =
Array (Int, Int) Char
showMatrix :: Matrix -> String
showMatrix m =
let
(_, (n, _)) = bounds m
row i =
[m ! (i, j) | j <- [0..n]]
in
unlines [row i | i <- [0..n]]
getMatrix :: Int -> [String] -> Matrix
getMatrix n rows =
array ((0, 0), (n - 1, n - 1)) $ do
(i, row) <- zip [0..] rows
(j, x) <- zip [0..] row
return ((i, j), x)
input :: Parser Matrix
input = do
n <- parseInteger
rows <- count n (endOfLine *> many1 digit)
return $ getMatrix n rows
solve :: Matrix -> Matrix
solve m =
let
b@(_, (n, _)) = bounds m
isCavity (i, j) =
let
v = m ! (i, j)
vUp = m ! (i - 1, j)
vDown = m ! (i + 1, j)
vLeft = m ! (i, j - 1)
vRight = m ! (i, j + 1)
in
i /= 0 && i /= n && j /= 0 && j /= n && v > vUp && v > vDown && v > vLeft && v > vRight
in
array b [if isCavity i then (i, 'X') else (i, m ! i)| i <- indices m]
main :: IO ()
main = do
res <- parseOnly input <$> T.getContents
case res of
Left err ->
fail err
Right m ->
putStrLn $ showMatrix $ solve m