查找两个数字是否具有相同的数字,然后从Haskell中的原始数字中删除它们

时间:2009-10-25 10:13:41

标签: haskell fractions

我正在做project euler question 33并且已经分解了一个重构来解决它,但我想不出如果在xy两个数字相同的情况下如何删除数字。 我到目前为止:

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? ]

不允许取消0。 它应该做的是:

49/98 {cancel the 9's}

得到:

结果是4/8。但我想不出如何从每个数字中删除常用数字。

1 个答案:

答案 0 :(得分:4)

xy成为两个数字。然后,可以删除x中与y共有的数字,如下所示:

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

翻转xy以删除y中的数字。这会使用xs Data.List.(\\) ys,从ys中删除xs中每个元素的第一个出现。


修改:您现在可能已经解决了problem 33。如果没有,让我给你一些提示:

我上面给出的代码,即read (show x \\ show y)并不适合这个问题。如果x等于 ab 并且y等于 ba ,对于某些数字 a b <会发生什么? / em>的

此问题的解决方案可以编写为单个列表解析。您可能希望使用Data.List.intersectData.List.nub在列表理解中创建以下术语:

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

现在s的范围超过了xy共有的数字。您可以使用

xy中删除这些内容
map (read . delete s . show) [x, y]

如果没有为你解决这个问题,我不能更明确,但我会再给你两个提示:

  • 在您的代码中编写y <- [10..99], x <- [10..y], x /= y。请注意,这可以更简洁地写为y <- [10..99], x <- [10..y-1]
  • 查看Data.Ratio,它提供了一种简单的方法来测试有理数的相等性,并自动计算其简化形式的分数的分子和分母。