Learn You a Haskell for Great Good 读书笔记 10

10. 用函数解决几个问题

  • Solve RPN

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    solveRPN :: String -> Double
    solveRPN = head . foldl f [] . words
    where f (x:y:ys) "*" = (y * x):ys
    f (x:y:ys) "+" = (y + x):ys
    f (x:y:ys) "-" = (y - x):ys
    f (x:y:ys) "/" = (y / x):ys
    f (x:y:ys) "^" = (y ** x):ys
    f (x:xs) "ln" = log x:xs
    f xs "sum" = [sum xs]
    f xs numberStr = read numberStr:xs

  • 最短路径

    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
    import Data.List
    data Section = Section { getA :: Int, getB :: Int, getC :: Int }
    deriving (Show)
    type RoadSystem = [Section]

    headthrowToLondon :: RoadSystem
    headthrowToLondon = [Section 50 10 30 ,
    Section 5 90 20 ,
    Section 40 2 25 ,
    Section 10 8 0 ]

    data Label = A | B | C deriving (Show)
    type Path = [(Label, Int)]

    optimalPath :: RoadSystem -> Path
    roadStep :: (Path, Path) -> Section -> (Path, Path)
    roadStep (p1, p2) (Section a b c) =
    let t1 = sum $ map snd p1
    t2 = sum $ map snd p2
    forward1 = t1 + a
    cross1 = t2 + b + c
    forward2 = t2 + b
    cross2 = t1 + a + c
    newP1 = if forward1 <= cross1
    then (A, a):p1
    else (C, c):(B, b):p2
    newP2 = if forward2 <= cross2
    then (B, b):p2
    else (C, c):(A, a):p1
    in (newP1, newP2)

    optimalPath roadSystem =
    let (bestA, bestB) = foldl roadStep ([], []) roadSystem
    in if sum (map snd bestA) <= sum (map snd bestB)
    then reverse bestA
    else reverse bestB


    groupsOf :: Int -> [a] -> [[a]]
    groupsOf 0 _ = undefined
    groupsOf _ [] = []
    groupsOf x ls = take x ls : groupsOf x (drop x ls)

    main = do
    contents <- getContents
    let threes = groupsOf 3 (map read $ lines contents)
    roadSystem = map (\[a,b,c] -> Section a b c) threes
    path = optimalPath roadSystem
    pathString = concat $ map (show . fst) path
    pathTime = sum $ map snd path
    putStrLn $ "The best path to take is: " ++ pathString
    putStrLn $ "Time taken: " ++ show pathTime