10. 用函数解决几个问题
Solve RPN
1
2
3
4
5
6
7
8
9
10solveRPN :: 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
52import 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