純度の数


27

今日は、Collat​​z関数fに関連するシーケンスaを見ていきます。

ここに画像の説明を入力してください

我々は、フォームのシーケンスを呼び出す...、Z、F(z)は、F(F(z)を)このCollat​​zシーケンス

最初の数私たちのシーケンスは、(1)は、ある0fを繰り返し適用すると、サイクル0→0→…

まだ見ていない最小の数は1で、a(2)= 1になります。fを繰り返し適用すると、サイクル1→4→2→1→…

これで、上のサイクルで数値2が見られたため、次に小さい数値はa(3)= 3で、サイクル3→10→5→16→8→4→2→1→4→2→1に分類されます→…

上記のすべてのサイクルで、すでに45を見てきたので、次の数はa(4)= 6です。

ここまでで、アイデアが得られるはずです。a(n)は、すべてのa(1)、…、a(n − 1)の Collat​​zシーケンスの一部ではない最小の数です。

正の整数nを指定するとa(n)を返すプログラムまたは関数を作成します。バイト単位の最短コードが優先されます。


テストケース:

1  -> 0
2  -> 1
3  -> 3
4  -> 6
5  -> 7
6  -> 9
7  -> 12
8  -> 15
9  -> 18
10 -> 19
50 -> 114

(これはOEISシーケンスA061641です。)



3
入力nは0から始まりますか?
ルイスメンドー

a(n+1) = a(n) odd: 3*a(n)+1, or a(n) even: a(n)/2
カールナップ

@LuisMendo申し訳ありませんが、どういうわけかあなたのメッセージを見逃しました。いいえ、チャレンジのように正確なシーケンスを再現します。
orlp

場合a:0ベースではありませんあなたはここで、「0ベースの話」しているようだ、なぜ私は理解していないa(n) is the smallest number that was not part of any Collatz sequences for all a(0), …, a(n − 1).
daniero

回答:


5

ゼリー20 19 バイト

ḟ@JḢ×3‘$HḂ?ÐĿ;Ṛ
Ç¡Ṫ

オンラインでお試しください!またはすべてのテストケースを確認します

使い方

Ç¡Ṫ              Main link. No explicit arguments. Default argument: 0
 ¡               Read an integer n from STDIN and do the following n times.
Ç                  Call the helper link.
  Ṫ              Tail; extract the last element of the resulting array.


ḟ@JḢ×3‘$HḂ?ÐĿ;Ṛ  Helper link. Argument: A (array)

  J              Yield all 1-based indices of A, i.e., [1, ..., len(A)]. Since 0
                 belongs to A, there is at least one index that does belong to A.
ḟ@               Filter-false swapped; remove all indices that belong to A.
   Ḣ             Head; extract the first index (i) that hasn't been removed.
           ÐĿ    Call the quicklink to the left on i, then until the results are no
                 longer unique. Collect all unique results in an array.
         Ḃ?      If the last bit of the return value (r) is 1:
       $           Apply the monadic 3-link chain to the left to r.
    ×3‘              Yield 3r + 1.
        H        Else, halve r.
              Ṛ  Yield A, reversed.
             ;   Concatenate the results array with reversed A.

n回の反復後、a(n + 1)の値は配列の先頭になります。新しい配列を古い配列の逆のコピーと連結するため、これはa(n)が最後になることを意味します。


9

Haskell、93 92バイト

c x|x<2=[[0,2]!!x]|odd x=x:c(3*x+1)|1<2=x:c(div x 2)
([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!)

使用例:([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!) 10-> 19

c xはCollat​​zサイクルのためxの少しの不正行為ですx == 1。メイン関数はすべての整数をループし、c xfor xにない整数を保持し[0..y-1]ます。定義のほぼ直接的な実装。Haskellのインデックス演算子!!は0ベース-1なので、インデックスを修正するために(さもなければ役に立たない)番号を先頭に追加することから始めます。


4

MATL46 40バイト

Oiq:"tX>Q:yX-X<`t0)to?3*Q}2/]h5M1>]Pv]0)

オンラインでお試しください!

説明

コードには、反復ごとに1つのCollat​​zシーケンスforを生成する外側のループがありnます。各シーケンスは、do...while新しい値を計算し、or が取得されるまでシーケンスベクトルに保存する内部ループによって生成されます。シーケンスの処理が完了すると、ベクトルが逆になり、以前のすべてのシーケンスの値を含むグローバルベクトルに連結されます。このベクトルには繰り返し値が含まれる場合があります。シーケンスベクトルを逆にすると、外側のループの終わりで、目的の結果(最後のシーケンスの開始値)がグローバルベクトルの終わりになります。10

擬似コード

1  Initiallization
2  Generate n sequences (for loop):
3    Compute initial value for the k-th sequence
4    Generate the k-th sequence (do...while loop)
5      Starting from latest value so far, apply the Collatz algorithm to get next value
6      Update sequence with new value 
7      Check if we are done. If so, exit loop. We have the k-th sequence
8    Update vector of seen values
9  We now have the n sequences. Get final result

コメントされたコード

O           % Push 0                                                          1
iq:         % Input n. Generate [1 2 ... n-1]                                 ·
"           % For loop: repeat n-1 times. Let k denote each iteration         2
  t         %   Duplicate vector of all seen values                           · 3
  X>Q       %   Take maximum, add 1                                           · ·
  :         %   Range from 1 to that: these are potential initial values      · ·
  y         %   Duplicate vector of all seen values                           · ·
  X-X<      %   Set difference, minimum: first value not seen                 · ·
  `         %   Do...while: this generates the k-th Collatz sequence          · 4
    t0)     %     Duplicate, push last value of the sequence so far           · · 5
    to      %     Duplicate, parity: 1 if odd, 0 if even                      · · ·
    ?       %     If odd                                                      · · ·
      3*Q   %       Times 3, plus 1                                           · · ·
    }       %     Else                                                        · · ·
      2/    %       Half                                                      · · ·
    ]       %     End if                                                      · · ·
    h       %     Concatenate new value of the sequence                       · · 6
    5M      %     Push the new value again                                    · · 7
    1>      %     Does it exceed 1? This is the loop condition                · · ·
  ]         %   End do...while. The loops ends when we have reached 0 or 1    · ·
  P         %   Reverse the k-th Collatz sequence                             · 8
  v         %   Concatenate with vector of previously seen values             · ·
]           % End for                                                         ·
0)          % Take last value. Implicitly display.                            9


3

Python 2、97 96バイト

r,=s={-1}
exec'n=r=min({r+1,r+2,r+3}-s)\nwhile{n}-s:s|={n};n=(n/2,3*n+1)[n%2]\n'*input()
print r

3の倍数がすべて純粋であるという事実を利用します。Ideoneでテストします。

使い方

最初の行に、r,=s={-1}セットS = {-1} (セット)及びR = -1

次に、STDINから整数を読み取り、特定の文字列を何度も繰り返して実行します。これは、次のPythonコードと同等です。

for _ in range(input())
    n=r=min({r+1,r+2,r+3}-s)
    while{n}-s:
        s|={n}
        n=(n/2,3*n+1)[n%2]

各反復で、sに属さない{r + 1、r + 2、r + 3}の最小メンバーを見つけることから始めます。最初の反復では、これによりr0に初期化されます

後続のすべての実行で、sにr + 1r + 2およびr + 3の一部が含まれる可能性がありますが、3の倍数はすべて純粋であるため、すべてが含まれることはありません。このステートメントを検証するには、3の倍数m3k + 1の形式ではないことに注意してください。これにより、2mが唯一の可能なプレイメージとして残ります。これも3の倍数です。よって、mが以下である、任意の数のこのCollat​​zシーケンスで現れることができないM、従って純粋です。

識別した後、Rをと初期化nは、我々が有するこのCollat​​z関数を適用するn=(n/2,3*n+1)[n%2]の各中間値加算、n個の集合にSを有しますs|={n}。すでにsにある番号nに遭遇すると、空のセットが生成され、反復が停止します。{n}-s

rの最後の値は、シーケンスの目的の要素です。


1
これに追加するには、3の倍数がすべて純粋であることの証明。3を法とするCollat​​zシーケンスを調べます。3x+ 1規則を適用すると、法は1になります。x/ 2規則を適用すると、mod 1が2になり、mod 2が1になります。開始値が既に半分になった3の倍数であった場合を除き、3の値。ただし、これらはまだ生成されていない大きな値なので、n = 0(mod 3)=> nは純粋です。
-orlp


1

Java、148バイト

int a(int n){if(n<2)return 0;int f=a(n-1),b,i,c;do{f++;for(b=1,i=1;i<n;i++)for(c=i==2?4:a(i);c>1;c=c%2>0?c*3+1:c/2)b=c==f?0:b;}while(b<1);return f;}

できた!(警告:ゼロ最適化による指数関数的な複雑さ。)

do...whileループからループに変換forするとゴルファーになりますが、そうするのに苦労しています。

ゴルフのアドバイスはいつものように大歓迎です。


それほどではありませんが、に変更for(b=1,i=1;i<n;i++)することで1バイトオフすることができfor(b=1,i=0;++i<n;)ます。ところで、私はあなたのイデオンが50のテストケースを逃している理由を理解していますが、なぜそれも10を逃していますか?問題なく処理できます。
ケビンCruijssen 16

@KevinCruijssenフォーマットが悪いからだ。
リーキー修道女

最高の改善ではありませんが、あまり時間をかけませんでした...(147バイト)int a(int n){if(n<2)return 0;int f=a(n-1),b=0,i,c;for(;b<1;){f++;for(b=1,i=1;i<n;i++)for(c=i==2?4:a(i);c>1;c=c%2>0?c*3+1:c/2)b=c==f?0:b;}return f;}
ポケ

1

Perl6、96

my @s;my $a=0;map {while ($a=@s[$a]=$a%2??3*$a+1!!$a/2)>1 {};while @s[++$a] {}},2..slurp;$a.say;

Perl 5の回答に基づきます。Perl6構文はPerl5構文よりも寛容ではないので、もう少し長くなりますが、今のところはこれで解決します。


0

PHP、233 124バイト

<?$n=$argv[1];for($c=[];$n--;){for($v=0;in_array($v,$c);)$v++;for(;$n&&!in_array($v,$c);$v=$v&1?3*$v+1:$v/2)$c[]=$v;}echo$v;

機能の+4:

function a($n){for($c=[];$n--;){for($v=0;in_array($v,$c);)$v++;for(;$n&&!in_array($v,$c);$v=$v&1?3*$v+1:$v/2)$c[]=$v;}return$v;}

0

Perl 5-74バイト

map{0 while 1<($a=$c[$a]=$a%2?$a*3+1:$a/2);0 while$c[++$a]}2..<>;print$a+0

これは非常に簡単なソリューションです。Collat​​z関数を変数に繰り返し適用し、値が見られたことを$a配列に保存し、@c0または1に達した後、$aまだ見られていない数値になるまで増分します。これは、入力マイナス2に等しい回数だけ繰り返され、最終的にの値$aが出力されます。


0

Mathematica、134バイト

f=If[EvenQ@#,#/2,3#+1]&;a@n_:=(b={i=c=0};While[i++<n-1,c=First[Range@Max[#+1]~Complement~#&@b];b=b~Union~NestWhileList[f,c,f@#>c&]];c)

読みやすい形式:

f = If[EvenQ@#, #/2, 3#+1] &;                        Collatz function
a@n_ := (                                            defines a(n)
  b = {i = c = 0};                                   initializations
                                                       b is the growing sequence
                                                       of cycles already completed
  While[i++ < n - 1,                                 computes a(n) recursively
    c = First[Range@Max[# + 1]~Complement~# & @b];   smallest number not in b
    b = b~Union~NestWhileList[f, c, f@# > c &]       apply f to c repeatedly
                                                       until the answer is smaller
                                                       than c, then add this new
                                                       cycle to b
    ]
  ; c)                                                 output final value of c
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.