Skip to content

Instantly share code, notes, and snippets.

@lotz84
Created October 11, 2014 08:21
Show Gist options
  • Save lotz84/edf9bdd676a405aef93d to your computer and use it in GitHub Desktop.
Save lotz84/edf9bdd676a405aef93d to your computer and use it in GitHub Desktop.
Solve given make 10 problem
{-
Example:
$ ./make10 7 6 9 5
(6,Plus,9,Divide,5,Plus,7)
(9,Plus,6,Divide,5,Plus,7)
-}
import System.Environment
import Control.Monad
import Data.List
import Data.Ratio
data Operator = Plus | Minus | Multiple | Divide deriving (Show, Eq)
type Expression = (Int, Operator, Int, Operator, Int, Operator, Int)
make10 :: [Int] -> [Expression]
make10 xs = do
x <- xs
y <- xs \\ [x]
z <- xs \\ [x, y]
w <- xs \\ [x,y,z]
o1 <- [Plus, Minus, Multiple, Divide]
o2 <- [Plus, Minus, Multiple, Divide]
o3 <- [Plus, Minus, Multiple, Divide]
return $ (x, o1, y, o2, z, o3, w)
apply :: Operator -> Ratio Integer -> Ratio Integer -> Ratio Integer
apply Plus x y = x + y
apply Minus x y = x - y
apply Multiple x y = x * y
apply Divide x y = x / y
calc :: Expression -> Maybe Int
calc (x, o1, y, o2, z, o3, w) =
let rx = toRational x
ry = toRational y
rz = toRational z
rw = toRational w
a1 = apply o1
a2 = apply o2
a3 = apply o3
result = rx `a1` ry `a2` rz `a3` rw
in if denominator result == 1
then Just $ (truncate.fromRational) result
else Nothing
main = do
args <- liftM (map (\x -> read x :: Int)) getArgs
if length args /= 4 then error "Input length must be 4" else return ()
mapM_ print $ nub.filter (\x -> calc x == Just 10) $ make10 args
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment