Fraction reduction: Difference between revisions

m
Line 1,362:
validIntegers :: [Int] -> [Int]
validIntegers xs = [x | x <- xs, not $ hasZeros x, hasUniqueDigits x]
 
hasUniqueDigits :: Integral a => a -> Bool
hasUniqueDigits n = length ds == length ul
where
dshasZeros = elem 0 . digits 10 n
ulhasUniqueDigits n = nublength ds == length ul
where
 
ds = digits 10 n
hasZeros :: Integral a => a -> Bool
ul = nub ds
hasZeros = elem 0 . digits 10
 
possibleFractions :: [Int] -> [Fraction]
Line 1,378 ⟶ 1,375:
, n < d
, gcd n d /= 1 ]
 
commonDigits :: Fraction -> [Int]
commonDigits (n1, n2) = digits 10 n1 `intersect` digits 10 n2
 
dropDigit :: Integral a => a -> a -> a
dropDigit d = digitsToIntegral . delete d . digits 10
 
digits :: Integral a => a -> a -> [a]
Line 1,394 ⟶ 1,385:
findReduction z@(n1, d1) = foldr f [] $ commonDigits z
where
commonDigits (n1, n2) = digits 10 n1 `intersect` digits 10 n2
decimal = realToFrac n1 / realToFrac d1
f x r | decimalWithDrop == decimal = (z, (n2, d2), x) : r
| otherwise = r
where
dropDigit d = digitsToIntegral . delete d . digits 10
n2 = dropDigit x n1
d2 = dropDigit x d1
Line 1,405 ⟶ 1,398:
findReductions = (findReduction =<<) . possibleFractions
 
displayResultshowReduction :: Reduction -> IO ()
displayResultshowReduction ((n1,d1),(n2,d2),d) = printf "%d/%d = %d/%d by dropping %d\n" n1 d1 n2 d2 d
 
displayCountshowCount :: [Reduction] -> Int -> IO ()
displayCountshowCount xs n = do
printf "There are %d %d-digit fractions of which:\n" (length xs) n
mapM_ (uncurry (printf "%5d have %d's omitted\n")) (countReductions xs) >> printf "\n"
Line 1,417 ⟶ 1,410:
main :: IO ()
main = do
mapM_ (\g -> mapM_ displayResultshowReduction (take 12 g) >> printf "\n") groups
mapM_ (uncurry displayCountshowCount) $ zip groups [2..]
where
groups = [ findReductions [10^1..99], findReductions [10^2..999]
Anonymous user