content: import Data.List
  import Data.Ratio
  import Control.Monad
  import System.Environment (getArgs)
  
  data Expr = Constant Rational |
      Expr :+ Expr | Expr :- Expr |
      Expr :* Expr | Expr :/ Expr
      deriving (Eq)
  
  ops = [(:+), (:-), (:*), (:/)]
  
  instance Show Expr where
      show (Constant x) = show $ numerator x
        -- In this program, we need only print integers.
      show (a :+ b)     = strexp "+" a b
      show (a :- b)     = strexp "-" a b
      show (a :* b)     = strexp "*" a b
      show (a :/ b)     = strexp "/" a b
  
  strexp :: String -> Expr -> Expr -> String
  strexp op a b = "(" ++ show a ++ " " ++ op ++ " " ++ show b ++ ")"
  
  templates :: [[Expr] -> Expr]
  templates = do
      op1 <- ops
      op2 <- ops
      op3 <- ops
      [\[a, b, c, d] -> op1 a $ op2 b $ op3 c d,
       \[a, b, c, d] -> op1 (op2 a b) $ op3 c d,
       \[a, b, c, d] -> op1 a $ op2 (op3 b c) d,
       \[a, b, c, d] -> op1 (op2 a $ op3 b c) d,
       \[a, b, c, d] -> op1 (op2 (op3 a b) c) d]
  
  eval :: Expr -> Maybe Rational
  eval (Constant c) = Just c
  eval (a :+ b)     = liftM2 (+) (eval a) (eval b)
  eval (a :- b)     = liftM2 (-) (eval a) (eval b)
  eval (a :* b)     = liftM2 (*) (eval a) (eval b)
  eval (a :/ b)     = do
      denom <- eval b
      guard $ denom /= 0
      liftM (/ denom) $ eval a
  
  solve :: Rational -> [Rational] -> [Expr]
  solve target r4 = filter (maybe False (== target) . eval) $
      liftM2 ($) templates $
      nub $ permutations $ map Constant r4
  
  main = getArgs >>= mapM_ print . solve 24 . map (toEnum . read)
  