Skip to content

Instantly share code, notes, and snippets.

@zindel
Created November 27, 2018 08:34
Show Gist options
  • Select an option

  • Save zindel/09c5c309e6f31197b3d742cb6f7b1941 to your computer and use it in GitHub Desktop.

Select an option

Save zindel/09c5c309e6f31197b3d742cb6f7b1941 to your computer and use it in GitHub Desktop.
module P93 where
data Expr = Operator Op
| Value Rational
deriving (Show, Eq)
data Op = Plus | Minus | Mul | Div deriving (Show, Eq, Enum, Bounded)
puzzle nums = [s1 ++ " = " ++ s2
| (p1, p2) <- split nums
, (s1,v1) <- genEq1 p1 Nothing
, (s2, v2) <- genEq1 p2 Nothing,
v1 == v2]
split :: [Rational] -> [([Rational], [Rational])]
split nums = [(take n nums, drop n nums) | n <- [1 .. length nums - 1]]
genEq1 :: [Rational] -> Maybe Op -> [(String, Rational)]
genEq1 [] _ = error "Cannot operate on empty list"
genEq1 [n] _ = [(showValue n, n)]
genEq1 ns parentOp = [
(wrap parentOp op $ s1 ++ showOp op ++ s2, applyOp op v1 v2)
| (p1, p2) <- split ns
, op <- [Plus .. Div]
, (s1, v1) <- genEq1 p1 (Just op)
, (s2, v2) <- genEq1 p2 (Just op)
]
wrap :: Maybe Op -> Op -> String -> String
wrap Nothing _ s = s
wrap (Just Plus) _ s = s
wrap (Just Minus) Mul s = s
wrap (Just Minus) Div s = s
wrap (Just Mul) Mul s = s
wrap _ _ s = wrap' s
wrap' s = "(" ++ s ++ ")"
applyOp Plus = (+)
applyOp Minus = (-)
applyOp Mul = (*)
applyOp Div = (/)
showOp Plus = "+"
showOp Minus = "-"
showOp Mul = "*"
showOp Div = "/"
showValue :: Rational -> String
showValue v = if toRational truncated == v
then show truncated
else show $ fromRational v
where truncated = ceiling $ fromRational v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment