Skip to content

Commit 31e5159

Browse files
committed
Haskell/99Questions/93_EvalPuzzle: Add
1 parent 7652a64 commit 31e5159

File tree

1 file changed

+19
-34
lines changed
  • Haskell/99Questions/93_EvalPuzzle

1 file changed

+19
-34
lines changed
+19-34
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,32 @@
11
import Data.List
22

33
main = print output
4-
output = genEqual [2,3,5,7,11]
4+
output = puzzle [2,3,5,7,11]
55

6-
data ExpNode = Const Float | BinOp Char ExpNode ExpNode deriving (Show)
6+
data ExpNode = Const Float | BinExp Char ExpNode ExpNode deriving (Show)
77

88
ops = "+-*/"
99
getOpPrior '+' = 1
1010
getOpPrior '-' = 1
1111
getOpPrior '*' = 5
1212
getOpPrior '/' = 5
1313

14-
reduceNodesList nodesL
15-
| all ((==1).length) nodesL = nodesL
16-
reduceNodesList nodesL = reduceNodesList$ concatMap reduceNodes nodesL
17-
where
18-
reduceNodes nodes@[n] = [nodes]
19-
reduceNodes nodes = concatMap buildAt [0..length nodes - 2]
20-
where
21-
buildAt i = [left++BinOp op h1 h2:right|op<-ops]
22-
where
23-
(left,h1:h2:right) = splitAt i nodes
24-
25-
buildTreeList l = map head $ reduceNodesList [map Const l]
26-
27-
getTreeVal (Const i) = i
28-
getTreeVal (BinOp op l r)
29-
| op == '+' = lv + rv
30-
| op == '-' = lv - rv
31-
| op == '*' = lv * rv
32-
| op == '/' && rv == 0 = lv / 0.000001
33-
| op == '/' = lv / rv
34-
where (lv,rv) = (getTreeVal l, getTreeVal r)
35-
36-
getTreeStr pPrior (Const i) = show $ floor i
37-
getTreeStr pPrior (BinOp op l r) = if curProir<pPrior then '(':raws++")" else raws
38-
where
39-
curProir = getOpPrior op
40-
raws = getTreeStr curProir l ++ [op] ++ getTreeStr (curProir+1) r
14+
evalByOp '+' l r = l + r
15+
evalByOp '-' l r = l - r
16+
evalByOp '*' l r = l * r
17+
evalByOp '/' l r
18+
| r == 0 = l / 0.00001
19+
| otherwise = l / r
4120

42-
genEqual l = concatMap genAt [1..length l - 1]
21+
getNodeStr pPrior (Const f) = show $ floor f
22+
getNodeStr pPrior (BinExp op l r) = if curPrior<pPrior then '(':str++")" else str
4323
where
44-
genAt i = [getTreeStr 0 lt++'=':getTreeStr 0 rt|(lt,lv)<-toValTreeList left,(rt,rv)<-toValTreeList right,lv==rv]
45-
where
46-
(left,right) = splitAt i l
47-
toValTreeList l = map (\t->(t,getTreeVal t)) $ buildTreeList l
24+
curPrior = getOpPrior op
25+
str = getNodeStr curPrior l ++ op: getNodeStr (curPrior + 1) r
26+
27+
splits l = init$ tail$ zip (inits l) (tails l)
28+
29+
toExpList [x] = [(x, Const x)]
30+
toExpList l = [(evalByOp op lv rv,BinExp op lt rt)|(left, right)<-splits l,(lv,lt)<-toExpList left,(rv,rt)<-toExpList right,op<-ops]
31+
32+
puzzle l = [getNodeStr 0 lt ++ '=':getNodeStr 0 rt|(left,right)<-splits l,(lv,lt)<-toExpList left,(rv,rt)<-toExpList right,lv==rv]

0 commit comments

Comments
 (0)