puzzle :: [Integer] -> [String] puzzle l = do i <- [1..length l-1] let (subl, subr) = splitAt i l (sl, vl, _) <- gen subl (sr, vr, _) <- gen subr if vl == vr then return (sl ++ " = " ++ sr) else [] gen :: [Integer] -> [(String, Rational, String)] gen (x:[]) = return (show x, fromInteger x, "_") gen l = do i <- [1..length l-1] let (subl, subr) = splitAt i l (sl, vl, opsl) <- gen subl (sr, vr, opsr) <- gen subr (ops, op) <- [("+", (+)), ("-", (-)), ("*", (*)), ("/", (/))] if (ops == "/" && vr == 0) || (ops == "+" && (opsr == "+" || opsr == "-")) || (ops == "*" && (opsr == "*" || opsr == "/")) then [] else return ((if opsl /= "_" && (ops == "*" || ops == "/") && (opsl == "+" || opsl == "-") then "(" ++ sl ++ ")" else sl) ++ " " ++ ops ++ " " ++ (if opsr /= "_" && ((ops == "-" && opsr /= "*" && opsr /= "/") || (ops == "*" && (opsr == "+" || opsr == "-")) || ops == "/") then "(" ++ sr ++ ")" else sr), op vl vr, ops)