2017-11-17 8 views
-1

良い午後の皆さん、私は学校の次の問題を解決する必要があります。Collat​​z Problemとの関係で、開始番号を1〜100万の間で見つけるアプリケーションを開発する必要があります最大の配列を生成する。linqを使用したCollat​​zシーケンス#

LINQを適用せずに次のコードを作成しました。この状況でlinqを使用する方法を知りたいと思います。

var sequence_size = 0; 
     var best_number = 0; 
     var sequence = 0; 


     for (var i = 0; i <= 1000000; i ++) 
     { 
      var size_ = 1; 
      sequence = i; 

      while (sequence! = 1) 
      { 

       sequence = sequence% 2 == 0? sequence/2: sequence * 3 + 1; 
       size ++; 
      } 

      if (size> size) 
      { 
       size_sequence = size; 
       best_number = i; 
      } 
     } 
+1

これまでに何を試しましたか?集計を見てください。 –

+5

'if(size> size)'?それはうまくいかないでしょう。 – juharr

+0

なぜですか?利点はなく、おそらく論理を難読化して、あなたにキディショーのようなものを見せるようにします(そして、あなたは他の人にあなたのためにそれをやろうとしています)。 – Rob

答えて

0

これは私がお勧めするものである。このように使用することができます

public class MaxSequenceFinder 
{ 
    public int FindBestCollatzSequence(int start, int count) 
    { 
     return Enumerable.Range(start, count) 
      .Select(n => new { Number = n, SequenceLength = CalcCollatzSequence((long)n) }) 
      .Aggregate((i, j) => i.SequenceLength > j.SequenceLength ? i : j) 
      .Number; 
    } 

    private int CalcCollatzSequence(long n) 
    { 
     int sequenceLength = 0; 

     do 
     { 
      n = CalcNextTerm(n); 
      sequenceLength++; 
     } 
     while (n != 1); 

     return sequenceLength; 
    } 

    private long CalcNextTerm(long previousTerm) 
    { 
     return previousTerm % 2 == 0 ? previousTerm/2 : previousTerm * 3 + 1; 
    } 
} 

var finder = new MaxSequenceFinder(); 
int result = finder.FindBestCollatzSequence(1, 100); 
Console.WriteLine(result); 

1 000 000のカウントのためにそれを実行するにはしばらく時間がかかります。この場合には(< 100)最長の配列は:返す関数を作成

public static class Ext { 
    public static T MaxBy<T, TKey>(this IEnumerable<T> src, Func<T, TKey> key, Comparer<TKey> keyComparer = null) { 
     keyComparer = keyComparer ?? Comparer<TKey>.Default; 
     return src.Aggregate((a,b) => keyComparer.Compare(key(a), key(b)) > 0 ? a : b); 
    } 
} 

97 
+0

Wikipediaによると、最長シーケンスは837,799で524ステップになるはずです。 113383を計算するときに 'int32'を超えます。 – NetMage

+0

@NetMage、true。あなたはInt64で十分だろうと思いますか? –

+0

はい、長くても「n」で十分です。あなたの答えが元の問題を解決するわけではないことに注意してください。最長シーケンスを生成する 'n'には言いません。 – NetMage

0

は各要素に対して関数を用いて配列の最大値を見つけるために拡張機能を作成します数のこのCollat​​z長さ:

public long Collatz(long seq) { 
    long len = 0; 

    while (seq != 1) { 
     if (seq % 2 == 0) { 
      seq /= 2; 
      ++len; 
     } 
     else { 
      seq = (3 * seq + 1)/2; 
      len += 2; 
     } 
    } 
    return len; 
} 

次に、あなたがコンピュータの範囲のための答えこれらとLINQを使用することができます。

var maxn = Enumerable.Range(2, 1000000-2).Select(n => new { n, Collatz = Collatz(n) }).MaxBy(nc => nc.Collatz).n; 
関連する問題