2012-03-08 10 views
3

私は(ProjectEuler.netから - Problem 14)は、次の問題を抱えているプロジェクトオイラー溶液#14

次の反復シーケンスは正の整数の集合のために定義されています

n -> n/2 (n is even) 
n -> 3n + 1 (n is odd) 

は、上記のルールを使用し、 13で始まる、私たちは次のシーケンスを生成:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 

をこのシーケンスは(13から始まり、で仕上げていることがわかります)には10項が含まれています。まだ証明されていませんが(Collat​​z Problem)、開始番号はすべて1で終わると考えられます。

最初の数字は100万未満で最長のチェーンを生成しますか?

注:チェーンが開始されると、条件は100万を超えることができます。

は、私が使用:

static int road (int n) 
    { 
     int road = 0; 
     while (n != 1) 
     { 
      if (n % 2 == 0) 
       n = n/2; 
      else 
       n = 3 * n + 1; 
      road++; 
     } 
     return road; 
    } 
    static void Main(string[] args) 
    { 
     int max = 0, num = 0; 
     for (int i = 1; i < 1000000; i++) 
     { 
      if (road(i) > max) 
      { 
       max = road(i); 
       num = i; 
      } 
     } 
     Console.WriteLine(num); 
    } 

しかし、何も出力が印刷されません。

答えて

11

(私は、私たちは、プロジェクトオイラーは、あなたが考えるを作るために意図されているので、あなたに完全なソリューションを提供するために、既に問題を解決した人ではないつもりはありません。)

方法を考え出すお試しくださいチェーンの値が大きいと、limits for integral typesが覚えています。

+1

ありがとう、私はそれを考え出しました:) – Novak

+0

良い。私は瑕疵を直接指摘したくありませんでした;-) – Joey

+2

+1正しいレベルの舵取り – spender

0

「何も出力されていません」というのは、非常に長く実行されているだけです。 for-loopの上限を100000に変更すると、すぐに出力されることがわかります。非常に長く実行される理由は、チェックされていない整数を使用し、オーバーフロー例外を取得しないことです。数秒後にブレイクすると、負の値nが表示されます。

checkedキーワードと、私が何を意味するか説明しますつまり、次のことを試してみてください。

// will now throw OverflowException with large n 
checked 
{ 
    int road = 0; 
    while (n != 1) 
    { 
     if (n%2 == 0) 
      n = n/2; 
     else 
      n = 3*n + 1; 
     road++; 
    } 
    return road; 
} 
0

まず、処理の無駄である、あなたは二回反復ごと道路()関数を呼び出していることに注意してください(そして「副作用を伴う機能のために、望ましくない結果をもたらす可能性がある」)。

第2に、整数オーバーフローに、あなたは答えを得ることができない - 値113383を、例えば、同じ20かそこらの数字

-122周りサイクリングしまい、-61、-182、 - -72、-74、-37、-110、-55、-164、-82、-41、-122

おっと!

1
function problem14(){ 

    function r(p,n){ 
     return cl(p)>cl(n)?p:n; 
    } 

    function c(n){ 
     return n%2===0?n/2:3*n+1; 
    } 

    function cl(n){ 
     var _a = 1; 
     var _n = n; 
     while(_n !== 1){ 
      _a++; 
      _n = c(_n); 
     } 
     return _a; 
    } 

    var b = []; 
    var m = 20; 
    var i = 500000; 
    while(i < 1000000){ 
     var _n = cl(i); 
     if(_n>m){ 
      b.push(i); 
      m = _n; 
     } 
     i++; 
    } 

    return b.reduce(r); 

} 

は、ここに私のJSコードです。

関連する問題