Đây nhe 😀 100/100 nào
import Data.Array
import Data.List
type Maze = [String]
type Position = (Int, Int)
markPath :: Maze -> (Int, Int) -> [Char] -> Maze
markPath maze start path = place maze positions
where
positions = getPositions start path
place :: Maze -> [(Int, Int, Char)] -> Maze
place = foldr (\(row, col, c) m -> replace m row col c)
replace :: Maze -> Int -> Int -> Char -> Maze
replace m row col c =
take row m ++
[take col (m !! row) ++ [c] ++ drop (col + 1) (m !! row)] ++
drop (row + 1) m
getPositions :: Position -> String -> [(Int, Int, Char)]
getPositions start@(r, c) path =
let moves = scanl getNextPos start path
marks = markSequence path
in zip3 (map fst moves) (map snd moves) marks
where
getNextPos (row, col) move = case move of
'd' -> (row+1, col)
'u' -> (row-1, col)
'l' -> (row, col-1)
'r' -> (row, col+1)
_ -> (row, col)
markSequence :: String -> [Char]
markSequence [] = "+"
markSequence [x] = "++"
markSequence (x:xs) = '+' : go x xs
where
go _ [] = "+"
go prev (curr:rest)
| isVertical prev curr = '|' : go curr rest
| isHorizontal prev curr = '-' : go curr rest
| otherwise = '+' : go curr rest
isVertical a b = (a `elem` "ud") && (b `elem` "ud")
isHorizontal a b = (a `elem` "lr") && (b `elem` "lr")
printMaze :: Maze -> IO ()
printMaze = putStr . unlines
sample1 :: Maze
sample1 = ["*********",
"* * * *",
"* * * * *",
"* * * * *",
"* * *",
"******* *",
" *",
"*********"]
main :: IO ()
main = do
putStrLn "Test path marking:"
printMaze $ markPath sample1 (1,1) "dddrruuurrdddrrddllllll"
Categories:
Code