Search code examples
haskellfractions

Finding if two numbers have the same digit and then remove them from in the original number in Haskell


I am doing project euler question 33 and have divised a refactor to solve it but I can't think of how to remove the digit if it is the same across both x and y. I got this far:

import Ratio
import List
p33 =  [ (x%y) | y <- [10..99] , x <- [10..y], (x `rem` 10) /= 0 , (y `rem` 10) /= 0 , x /= y , (length $ nub $ concat $ map decToList [x,y]) == 3 , [numerator(x%y),denominator(x%y)] == WHAT GOES HERE? ]

The cancelling of 0's is not allowed. What it should do is:

49/98 {cancel the 9's}

to get:

4/8 as the result. But I can't think of how to remove the common digits from each number.


Solution

  • Let x and y be the two numbers. Then one can remove the digits in x which it has in common with y like this:

    Prelude> import Data.List
    Prelude Data.List> let x = 68
    Prelude Data.List> let y = 76
    Prelude Data.List> read (show x \\ show y) :: Int
    8
    

    Flip x and y to remove digits from y. This uses xsData.List.(\\)ys, which removes the first occurrence of each element in ys from xs.


    Edit: you may have solved problem 33 by now. If not, let me give you some more hints:

    The code which I gave above, i.e. read (show x \\ show y) is not really suitable for this problem. What happens if x equals ab and y equals ba, for some digits a and b?

    The solution to this problem can be written as a single list comprehension. You may want to use Data.List.intersect and Data.List.nub to create the following term in your list comprehension:

    s <- nub $ intersect (show x) (show y)
    

    Now s ranges over the digits that x and y have in common. You can remove these from x and y using

    map (read . delete s . show) [x, y]
    

    I cannot be more explicit without solving the exercise for you, but I'll leave you with two more hints:

    • In your code you write y <- [10..99], x <- [10..y], x /= y. Observe that this can be written more succinctly as y <- [10..99], x <- [10..y-1].
    • Have a look at Data.Ratio, which provides an easy way to test the equality of rational numbers and automatically calculates the numerator and denominator of a fraction in its reduced form.