私は素数候補ごとに反復したい素数除数のシーケンスを持っています。私はGetEnumerator()MoveNext()とCurrentを使用します。列挙子を最初からやり直すことはできません。私は、コンパイルされたReset()を試みましたが、実装されていないランタイムエラーが発生します。F#:列挙子を再初期化したい
私はF#2.0インタラクティブ4.0.40219.1
任意の提案を構築し使用していますか?問題を明確にするために
よろしく、 ダグ
:各最有力候補についてNI(約の平方根のNまで)プライム除数シーケンスを通して反復し、完全要因たいNまたはそれが素数であるかどうかを判断。 GetEnumerator、MoveNextを使用して、現在のアプローチは最初のプライム候補には機能しますが、2番目のプライム候補では、最初から除数シーケンスを繰り返したいと思っています。これを行う唯一の方法は、新しいイテレータ(多数のプライム候補に対しては厄介です)を作成するか、新しいプライムシーケンス(私がしたくない)を作成することです。
"divisors in seqPrimes"のようなものを使用することの提案は、停止する前にすべての除数を使い果たしているように見えますが、素数の除数が分割するとすぐに停止したいと考えています。
上記の記述に私の論理に誤りがある場合は、私にお知らせください。
私はSeq.cacheを調査しましたが、これは私のために働いていました。結果のコードは次のとおりです。あなたは列挙子をリセットするために、あなたの試みの原因は素数のあなたのシーケンスを再生する高コストであることを意味する場合は、cachingあなたの順序を考慮することができる
// Recursive isprime function (modified from MSDN)
let isPrime n =
let rec check i =
i > n/2 || (n % i <> 0 && check (i + 2))
if n = 2 then true
elif (n%2) = 0 then false
else check 3
let seqPrimes = seq { for n in 2 .. 100000 do if isPrime n then yield n }
// Cache the sequence to avoid recomputing the sequence elements.
let cachedSeq = Seq.cache seqPrimes
// find the divisors of n (or determine prime) using the seqEnum enumerator
let rec testPrime n (seqEnum:System.Collections.Generic.IEnumerator<int>) =
if n = 1 then printfn "completely factored"
else
let nref = ref n
if seqEnum.MoveNext() then
let divisor = seqEnum.Current
//printfn "trial divisor %A" divisor
if divisor*divisor > n then printfn "prime %A" !nref
else
while ((!nref % divisor) = 0) do
printfn "divisor %A" divisor
nref := !nref/divisor
testPrime !nref seqEnum
// test
for x = 1000000 to 1000010 do
printfn "\ndivisors of %d = " x
let seqEnum = cachedSeq.GetEnumerator()
testPrime x seqEnum
seqEnum.Dispose() // not needed
'for x in y'構文を使用するだけで、実際にはIEnumeratorでメンバーを明示的に呼び出す必要はほとんどありません。もしあなたが必要ならば;新しい列挙子を作成するだけです。あなたのコードを投稿することは、私たちがより良い選択肢を見つけることができると思うので役に立ちます。 – vcsjones
エラーを具体的に示す例がありますか? – pad
Seq.cacheを使用しようとしましたか? – Huusom