あらゆる可能なサイクル長


21

入力を受け取り、出力を提供する関数(またはプログラム)は、独自の出力で関数を繰り返し呼び出して最終的に元の数に達した場合、サイクルを持っていると言えます。たとえば、次の関数を使用します。

Input:  n    1 2 3 4 5 6
Output: f(n) 5 7 1 3 4 9

我々が開始するとn=1f(n)=5f(f(n))=f(5)=4f(f(f(n)))=f(4)=3f(f(f(f(n))))=f(3)=1

これは書かれてい(1 5 4 3)ます。このループには4つの一意の番号があるため、これは長さ4のサイクルです。


あなたの課題は、あらゆる長さのサイクルを持つプログラムまたは関数を書くことです。つまり、長さ1、長さ2などのサイクルが必要です。

さらに、関数/プログラムは正の整数から正の整数である必要があります。また、すべての正の整数にわたって、可能な出力値ごとに1つの入力値が存在する必要があることを意味するbijectiveでなければなりません。別の言い方をすれば、関数/プログラムは正の整数の順列を計算する必要があります。


詳細:STDIN、STDOUT、関数の引数、戻り値など、標準の入出力システムはすべて許可されます。標準の抜け穴は禁止されています。

データ型の制限について心配する必要はありません-上記のプロパティは、たとえば、任意の値を保持できる、intまたはfloat任意の値を保持できるという仮定の下でのみ保持する必要があります。

正の整数ではない入力に対する関数の動作に制限はなく、これらの入力/出力は無視されます。


得点はバイト単位のコードゴルフで、最短のコードが勝ちです。


「長さ1、長さ2、などのサイクルが必要です」これを「少なくとも長さ1、少なくとも長さ2などのサイクルが必要」または「こと正確に長さ1の周期、長さ2のいずれか、及びそう「に。
バクリウ

@Bakuriu各正の長さの少なくとも1つのサイクル。
isaacg

回答:


11

Pyth、11 8バイト

.<W-0zz1

以前の答えよりもずっと退屈です。

0桁を含むすべての数字は、それ自体にマッピングされます。他の数字は、数字が1回転した数字にマッピングされます。たとえば、次のようになります。

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

8

パイソン2、56の 55 54バイト

n=input()
a=b=1
while a+b<=n:a+=b;b+=1
print(n+~a)%b+a

最初の21の出力は次のとおりです。

[1, 3, 2, 6, 4, 5, 10, 7, 8, 9, 15, 11, 12, 13, 14, 21, 16, 17, 18, 19, 20]

リストを次のようにチャンクに分割すると、パターンは明らかです。

 1    2  3    4  5  6    7  8  9  10    11  12  13  14  15    16  17  18  19  20  21
[1]  [3, 2]  [6, 4, 5]  [10, 7, 8, 9]  [15, 11, 12, 13, 14]  [21, 16, 17, 18, 19, 20]

くそー、これも私が目指していたパターンですが、閉じた形です。
orlp

1
興味深い.. a値はシーケンスA000124に従います。P:しかし、私はあなたが既に知っていたことを推測する
カーデ

このシーケンスはoeis.org/A066182であることに注意してください。
orlp

8

Pyth、25バイト

+hK/*J/h@h*8tQ2 2tJ2%-QKJ

これは@ Sp3000と同じシーケンスですが、閉じた形式です。閉じた形式は次のとおりです。

M(n)= floor((1 + sqrt(1 + 8 *(n-1)))/ 2) B(n)= M(n)*(M(n)-1)/ 2 f(n)= B(n)+((n-B(n)+ 1)mod M(n))


5

Python3、40バイト

n=input();print([n[1:]+n[0],n]['0'in n])

0桁を含むすべての数字は、それ自体にマッピングされます。他の数字は、数字が1回転した数字にマッピングされます。たとえば、次のようになります。

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

1
既視感!2か国語で表示できるのはすばらしいことです。
デンハムクート

3

ルビー、22 + 1 = 23

コマンドラインフラグを使用して-p、実行

~/(.)(.?)/
$_=$1+$'+$2

入力として数値の文字列表現(末尾の改行なし)が与えられると、最初の数字を一定に保ち、残りを左に回転させるため、に1234なり1342ます。

これはで21文字に減らすことができます $_=$1+$'+$2if/(.)(.)/が、警告を出力します。


3

ルビー、16 + 1 = 17

コマンドラインフラグを使用して-p、実行

$_=$_[/.0*$/]+$`

これは他の答えよりも複雑な機能ですが、たまたまゴルフができます(また、後続の改行にも耐性があります)。入力の最後のゼロ以外の数字に後続ゼロを加えて、数字の先頭に移動します。そう9010300なる3009010。n個のゼロ以外の数字を持つ数字は、長さnサイクルの一部になります。

入力はSTDINを介した任意のベースの文字列であり、出力はそのベースの文字列です。


2

Python、43

Sp3000の関数逆で、再帰的に実装されています。

f=lambda n,k=1:n>k and k+f(n-k,k+1)or n%k+1

この関数は、1サイクル、2サイクル、3サイクルの順に続きます...

(1)(2 3)(4 5 6)(7 8 9 10)(11 12 13 14 15)...

操作n%k+1k、数値のサイクルとして機能します1..kk使用する適切なものを見つけるには、すべてを下にシフトしk=1、次にk=2、...の順にシフトしますn<=k


2

Pyth、15バイト

これまでのところ、文字列演算ではなく数値演算を使用する最短の回答。

.|.&Q_=.&_=x/Q2

    Q                input
            /Q2      input div 2
           x   Q     that XOR input
          =          assign that to Q
         _           negate that
       .&       Q    that AND Q
      =              assign that to Q
     _               negate that
  .&                 input AND that
.|               Q   that OR Q

バイナリ表現に対するこの関数の効果は、1の右端のブロックを次の0に拡張することです。または、0がない場合は、1にリセットします1:

10010110100000 ↦  
10010110110000 ↦  
10010110111000 ↦  
10010110111100 ↦  
10010110111110 ↦  
10010110111111 ↦
10010110100000  

Pyth、26バイト、楽しいバリアント

.|.&Q_h.&/Q2+Qy=.&/Q2_h.|y

    Q                           input
         /Q2                    input div 2
             Q                  input
                  /Q2           input div 2
                         yQ     twice input
                       .|  Q    that OR input
                     _h         NOT that
                .&              (input div 2) AND that
               =                assign that to Q
              y                 twice that
            +                   input plus that
       .&                       (input div 2) AND that
     _h                         NOT that
  .&                            input AND that
.|                          Q   that OR Q

上記の操作を、右端のブロックだけでなく、ビット単位の算術演算のみを使用して、1のすべてのブロックに対して同時に実行します。

1000010001001 ↦
1100011001101 ↦
1110011101001 ↦
1111010001101 ↦
1000011001001 ↦
1100011101101 ↦
1110010001001 ↦
1111011001101 ↦
1000011101001 ↦
1100010001101 ↦
1110011001001 ↦
1111011101101 ↦
1000010001001

1

Swift 1.2、66バイト

func a(b:Int){var c=0,t=1,n=b
while n>c{n-=c;t+=c++}
print(n%c+t)}
Input:  1,   2, 3,  4, 5, 6,   7, 8, 9, 10,   11, 12, 13, 14, 15
Output: 1,   3, 2,  5, 6, 4,   8, 9, 10, 7,   12, 13, 14, 15, 11

1

Brachylog、5バイト

∋0&|↺

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

@orlpのPyth回答のポート。シンプルできれいになります:

∋0    % If input contains a 0 (since input is a single number, "contains" ∋ treats it as an array 
      %   of its digits, so this means "if any of input's digits are 0")
&     % Then output is the input
|     % Otherwise
↺     % Circularly shift the input once, and unify that with the output

もともと@ Sp3000のPythonソリューションを移植したかったのですが、それには23バイトもかかりました。

⟧∋B-₁⟦++₁A≤?;A--₁;B%;A+

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


0

JavaScript(ES6)、43バイト

f=(n,i=1,j=1)=>n>j?f(n,++i,j+i):n++<j?n:n-i

0

Matlab(189)

  function u=f(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if ~isempty(z),t=y(y~=max(y));if isempty(t),u=y(end)*2^(nnz(y)-1);else,g=max(t);e=primes(g*2);u=n/g*e(find(e==g)+1);end,end,end

  • 関数:

    素数に従って整数をマッピングします。数値がnilであるか、2または1に因数分解されている場合、数値はそれ自体にマッピングされます。すべての因子のすべての指数の合計である数biggest_prime^nに達するまで、より大きな素因数n、その量に達すると、max_prime*2^(n-1)再び同じサイクルを再現します。


0

Matlab(137)

  function u=h(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if~isempty(z),e=nnz(y);f=nnz(z);if(~mod(e,f)&e-f)u=n/2^(e-f);else,u=u*2;end

  • 少し似たアプローチで、他の素因数の指数の和で割り切れる2指数に出会うまで{0,1,2 ^ n}に等しくない数を徐々に乗算し2ます。次に、で割るサイクルの開始点に移動し2^(sum of exponents of other primes)ます。他の数値はそれ自体にマッピングされます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.