Skip to content

Instantly share code, notes, and snippets.

@autotaker
Created March 15, 2014 05:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save autotaker/9562047 to your computer and use it in GitHub Desktop.
Save autotaker/9562047 to your computer and use it in GitHub Desktop.
import Data.List
import Data.Char
import Control.Monad
data Expr = Number Int | Op Char
instance Show Expr where
show (Number x) = show x
show (Op ch) = [ch]
type Ops a = [(a -> a -> [a], Char )]
solve :: (Num a,Eq a) => [Int] -> Int -> Ops a -> [[Expr]]
solve xs ans ops = go [] xs
where
go [x] [] | x == fromIntegral ans = return []
go (x1:x2:l) xs = shift (x1:x2:l) xs `mplus` reduce x1 x2 l xs
go l xs = shift l xs
shift l xs = do
x <- xs
r <- go (fromIntegral x:l) (delete x xs)
return (Number x:r)
reduce x1 x2 l xs = do
(op,ch) <- ops
x3 <- op x1 x2
r <- go (x3:l) xs
return (Op ch:r)
ops1 :: Ops Rational
ops1 = [ (add,'+'),(sub,'-'),(mul,'*'),(divZero,'/') ]
where
add a b = return (a+b)
sub a b = return (a-b)
mul a b = return (a*b)
divZero a b | b == 0 = [] | otherwise = return (a/b)
ops2 :: Ops Int
ops2 = [ (add,'+'),(sub,'-'),(mul,'*'),(div','/') ]
where
add a b = return (a+b)
sub a b | a < b = [] | otherwise = return (a-b)
mul a b = return (a*b)
div' a b | b == 0 || mod a b /= 0 = []
| otherwise = return (div a b)
showExpr :: [Expr] -> String
showExpr = go []
where
go [s] [] = s
go (s1:s2:ss) (op:l) | isOp op = go ((unparen $ unwords [s1,show op,s2]):ss) l
go ss (x:l) = go (show x:ss) l
isOp (Op _) = True
isOp _ = False
unparen s = "(" ++ s ++ ")"
main :: IO ()
main = do
let l = do
d1 <- [0..9]
d2 <- [d1..9]
d3 <- [d2..9]
d4 <- [d3..9]
return [d1,d2,d3,d4]
forM_ l $ \xs -> do
let s = map intToDigit xs
let ans1 = solve xs 10 ops1
let ans2 = solve xs 10 ops2
when (null ans1) $ do
putStrLn $ s ++ " no answer"
when (null ans2 && not (null ans1)) $ do
putStrLn $ s ++ " " ++ show (length ans1) ++ " " ++ showExpr (head ans1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment