4

我试图找到一些特殊的数字,这样当它除以 2 时得到 1,除以 3 时得到 2,依此类推,直到 6。

这非常有效。

[ x | x <- [1..1000],x `mod` 2 == 1 , x `mod` 3 == 2 , x `mod` 4 == 3 , x `mod` 5 == 4 , x `mod` 6 == 5]

答:

[59,119,179,239,299,359,419,479,539,599,659,719,779,839,899,959]

我正在努力使它变得更好,以免它太冗长,但以下内容不起作用。

[ x | x <- [1..1000], y <- [2..6], x `mod` y == (y-1) ]

它需要所有y满足条件的 x,但我想要的是,我想要满足所有y 条件的 x。

4

3 回答 3

3

列表理解很短,但通常晦涩难懂。编写/读取一元代码通常更容易。让我们翻译第一个版本

do
x <- [1..1000] -- here a value is selected
guard $ x `mod` 2 == 1  -- it checked
guard $ x `mod` 3 == 2 -- and checked
guard $ x `mod` 4 == 3 
guard $ x `mod` 5 == 4 
guard $ x `mod` 6 == 5 -- you got the point
return x -- value returned

第二个是

do
x <- [1..1000] -- value selected
y <- [2..6]  -- another value selected
guard $ x `mod` y == (y-1) -- the pair of previously selected values is checked 
return x -- and now the first value returned.

===

第二个写对了:

do
x <- [1..1000]
guard $ and $ do
              y <- [2..6] 
              return $ x `mod` y == 1
return x

它可以通过多种方式重写,包括

[x | x <- [1..1000], and [x `mod` y == 1 | y <- [2..6] ] ]
于 2012-07-09T18:57:01.370 回答
2

仅作记录,您仍然可以从第二次尝试中“恢复”解决方案:

import Data.List

map head $ filter ((==5).length) $ group [ x | x <- [1..1000], y <- [2..6], x `mod` y == (y-1) ] 
于 2012-07-09T21:27:28.397 回答
2

您可以将条件写为

[ x | x <- [1..1000], all (\y -> x `mod` y == y-1) [2 .. 6]]

但是在这种特定情况下你可以做得更好,

let modulus = foldl1 lcm [2 .. 6]
[x | x <- [1 .. 1000], x `mod` modulus == modulus - 1]
[modulus - 1, 2*modulus - 1 .. 1000]  -- even better
于 2012-07-09T17:37:41.960 回答