Final Exam

Đâ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

Leave a reply

Your email address will not be published. Required fields are marked *