2016-11-18 6 views
2

私は これはなぜ幸運な数字を生成しないのですか?

static IEnumerable<int> LuckyNumbers() 
{ 
    IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue); 
    int counter = 1; 
    while (true) 
    { 
    int number = luckyNumbers.ElementAt(counter++); 
    yield return number; 
    luckyNumbers = luckyNumbers.Where((_, index) => (index + 1) % number != 0); 
    } 
} 

lucky numbersを生成する関数を記述しようとしていますが、これは生成:幸運の数字ではありません

2,5,7,11,13,17,21,... 

を。

なぜ私のコードは機能しませんか?すべての自然数と

  1. 開始:私がしようとしていますそれらを介して

    IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue); 
    int counter = 1; 
    
  2. 反復処理し、次のラッキーナンバーを返す:

    while (true) 
    { 
        int number = luckyNumbers.ElementAt(counter++); 
        yield return number; 
    
  3. をすべてn番目の番号を削除配列から:

    luckyNumbers = luckyNumbers.Where((_, index) => (index + 1) % number != 0); 
    

これは私が意図したとおりに動作しない理由はわかりません。

+2

ステップ3を実行するたびに、新しいシーケンスが作成されることに注意してください。さて、あなたはその新しいシーケンスから要素の 'counter'を欲しいと確信していますか?紙の上でそれをすべて試してみてください... –

+0

@JonSkeet私は確信しています、私は毎回前の世代の次の要素を取ることを意味していると思っています。しかし私は紙でそれを試すことができます。 – theonlygusti

+2

wikipediaには実例がありますので、デバッグ中はそれに従うことをお勧めします。最初の問題は、 'counter = 0'ではなく' counter = 1'を得ているので、2番目の要素から始めていることです。つまり、1を返すことは決してありません.1は幸運な数字です。 –

答えて

0

あなたのコードが動作しない理由はいくつかあります:

  1. コレクションはプログラミングでは、ゼロから始まるインデックスです。これがインデックス1の番号であるため、最初の番号は2です。counterを0に初期化する必要があります。
  2. 1にカウンタを初期化して、1番目の番号を取り消さないようにします効果的にすべての数字を殺すので、与えられた位置の要素を取ることは失敗する運命です)。問題は幸運な数字の定義にあります。最初の幸運な数字は1ですが、最初の反復はすべての2番目のの数字を打つことです。だからあなたはMath.Min(number, 2)を取らなければならない。

最後に、あなたは次のように到着:

static IEnumerable<int> LuckyNumbers() 
    { 
     IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue); 
     int counter = 0; 
     while (true) 
     { 
      int number = luckyNumbers.ElementAt(counter++); 
      yield return number; 
      int moduloCheck = Math.Max(number, 2); 
      luckyNumbers = luckyNumbers.Where((_, index) => (index + 1) % moduloCheck != 0); 
     } 
    } 

パフォーマンスの観点からは、しかし、私はあなたが繰り返しElementAtで永遠に最初の数字をチェックするように、溶液が多数のために恐ろしいことだと思います。 where式は索引付け不可能なので、これは常にいくつかのwhere条件の各数値のチェックを開始します。あなたが最初にn幸運な数字を得るためにそれを単にLuckyNumbers().Take(n)として使用することができることは良いことです。

+0

"シーケンスの1番目の数字をキャンセルしないようにカウンタを1に初期化したと思います。" - これは本当です。 – theonlygusti

関連する問題