module Main (main) where import Text.Printf (printf) lq :: [(Int, Int)] lq = [(i, 10 - i) | i <- [1 .. 9]] lqjk :: [(Int, Int, Int, Int)] lqjk = do (l, q) <- lq -- take l and q values from the lq list jpk <- [9 - l, 18 - l] -- the sum of j and k (j, k) <- [(i, jpk - i) | i <- [1 .. min 9 jpk]] -- possible values of j and k if 8 * l + 9 /= 10 * j + k -- if the equality is not satisfied then [] -- we do not have a solution else return (l, q, j, k) -- otherwise, success! xyzlqjk :: [(Int, Int, Int, Int, Int, Int, Int)] xyzlqjk = do (l, q, j, k) <- lqjk let zyx = 3 * (10 * l + q) let (zy, x) = divMod zyx 10 let (z, y) = divMod zy 10 if z > 0 && z < 10 -- making sure that there is a third digit and not a fourth one then [(x, y, z, l, q, j, k)] -- it's an actual three-digit number :) else [] -- :( xyzprlqjk :: [(Int, Int, Int, Int, Int, Int, Int, Int, Int)] xyzprlqjk = do (x, y, z, l, q, j, k) <- xyzlqjk let pqr = 6 * (10 * l + q) let (pq, r) = divMod pqr 10 let (p, q) = divMod pq 10 if p > 0 && p < 10 -- same thing, just need to guarantee that PQR is, in fact, a three-digit number then [(x, y, z, p, r, l, q, j, k)] else [] main :: IO () main = sequence_ $ do (x, y, z, p, r, l, q, j, k) <- xyzprlqjk -- take every possible collection of values if 100 * z + 10 * y + x /= 3 * (10 * l + q) then [] -- if ZYX/3 ≠ LQ, we do not have a solution else if 100 * p + 10 * q + r /= 6 * (10 * l + q) then [] -- if PQR/6 ≠ LQ, same issue else if 100 * j + 10 * k + l /= 9 * (10 * l + q) then [] -- again with JKL/9 ≠ LQ; these checks shuold be redundant else return $ printf "%d%d%d / 3 = %d%d%d / 6 = %d%d%d / 9 = %d%d" z y x p q r j k l l q -- but i don't want to report fake solutions