|
1 | 1 | import Data.List
|
2 | 2 |
|
3 | 3 | main = print output
|
4 |
| -output = genEqual [2,3,5,7,11] |
| 4 | +output = puzzle [2,3,5,7,11] |
5 | 5 |
|
6 |
| -data ExpNode = Const Float | BinOp Char ExpNode ExpNode deriving (Show) |
| 6 | +data ExpNode = Const Float | BinExp Char ExpNode ExpNode deriving (Show) |
7 | 7 |
|
8 | 8 | ops = "+-*/"
|
9 | 9 | getOpPrior '+' = 1
|
10 | 10 | getOpPrior '-' = 1
|
11 | 11 | getOpPrior '*' = 5
|
12 | 12 | getOpPrior '/' = 5
|
13 | 13 |
|
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 |
41 | 20 |
|
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 |
43 | 23 | 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