yingpotter

[99p]ArithPuz

Aug 12th, 2011
982
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.List
  2.  
  3. ------ Predefined Consts
  4. inputNum5 = ["2","3","5","7","11"]
  5. inputNum6 = ["2","3","5","7","11","13"]
  6. inputNum7 = ["2","3","5","7","11","13","17"]
  7. inputNum8 = ["2","3","5","7","11","13","17","19"]
  8. rpn1 = ["5", "1", "2", "+", "4", "*", "+", "3", "-"]
  9. arithop = ["*", "/", "+", "-"]
  10.  
  11. ------ Reverse Polish Notation Calculator, Permutator
  12. rpnCalc :: [[Char]] -> Float
  13. rpnCalc list = head (foldl rpnReader [] list)
  14.                where rpnReader :: (Read a, Fractional a) => [a] -> [Char] -> [a]
  15.                      rpnReader (x:y:xs) "+" = (x + y):xs
  16.                      rpnReader (x:y:xs) "-" = (y - x):xs
  17.                      rpnReader (x:y:xs) "*" = (x * y):xs
  18.                      rpnReader (x:y:xs) "/" = (y / x):xs
  19.                      rpnReader xs numstr = read numstr:xs
  20. rpnVerify :: [[Char]] -> Bool
  21. rpnVerify ls = and (map (\x -> (length $ filter (`elem` arithop) x) < (length $ filter (`notElem` arithop) x)) (inits ls \\ [[]]))
  22.                && ((length $ filter (`notElem` arithop) ls) - (length $ filter (`elem` arithop) ls) == 1)
  23. opPermu :: Int -> [[[Char]]]
  24. opPermu n = opPermu' n [[]]
  25.            where opPermu' :: Int -> [[[Char]]] -> [[[Char]]]
  26.                   opPermu' 0 oplists = oplists
  27.                  opPermu' n oplists = opPermu' (n-1) [ oplist ++ [op] | oplist <- oplists, op <- arithop ]
  28. rpnGen :: [[Char]] -> [[Char]] -> [[[Char]]]
  29. rpnGen ns ops = rpnGen' (length ns + length ops) ns ops [[]]
  30.                 where rpnGen' :: (Num a) => a -> [[Char]] -> [[Char]] -> [[[Char]]] -> [[[Char]]]
  31.                      rpnGen' 0 _ _ rpnlists = rpnlists
  32.                       rpnGen' _ [] ops rpnlists = map (++ops) rpnlists
  33.                      rpnGen' _ _ [] rpnlists = []
  34.                       rpnGen' len (n:ns) (o:ops) rpnlists = rpnGen' (len-1) ns (o:ops) (map (++[n]) rpnlists) ++
  35.                                                             rpnGen' (len-1) (n:ns) ops (map (++[o]) $ filter (\x -> (length $ filter (`notElem` arithop) x) > (length $ filter (`elem` arithop) x)) rpnlists)
  36. rpnPermu :: [[Char]] -> [[[Char]]]
  37. rpnPermu [] = []
  38. rpnPermu (n:ns) = map ([n]++) $ concatMap (rpnGen ns) $ opPermu (length ns)
  39.  
  40. ------ Puzzle Solver
  41. arithPuz :: [[Char]] -> [([[Char]], [[Char]])]
  42. arithPuz numlist = concatMap rpnPair [ splitAt i numlist | i <- [1..length numlist - 1] ]
  43.                   where rpnPair listpair = [ (a,b) | a <- rpnPermu (fst listpair), b <- rpnPermu (snd listpair), rpnCalc a == rpnCalc b ]
  44.                  
  45. ------ Currently too lazy to write a RPN -> Infix Notation converter >_<
Advertisement
Add Comment
Please, Sign In to add comment