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

そして2番目は

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.

===

2番目に正しく書かれています:

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

条件は次のように書くことができます

[ 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 に答える
2

念のために言っておきますが、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 に答える