あらゆる長さのサイクルを持つ関数を見つける


11

機能は持っていると言われている長さの周期をN個存在する場合、Xをそのドメイン、その結果、F N(X)= XF M(X)≠X0 <M <N 、上付き文字nは意味N - fのアプリケーションを折りたたみます。長さ1のサイクルは固定小数点f(x)= xであることに注意してください。

あなたの仕事は、整数から自身への全単射関数を実装することです。これは、すべての正の長さnの正確に1サイクルを持ちます。全単射関数は1対1の対応です。つまり、すべての整数が1回だけマッピングされます。長さの正確に一つの周期を有するN正確に存在することを意味し、Nの異なる番号がxはれるF N(X)= XF M(X)≠X0 <M <N

このような関数がx = 0の周りにどのように見えるかの例を次に示します

x     ... -7 -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6  7 ...
f(x)  ...  2  4  6 -3 -1  1 -4  0 -2  5  7 -7 -6  3 -5 ...

この抜粋は、長さのサイクルが含ま15

n   cycle
1    0
2   -2  1
3   -4 -3 -1
4   -5  6  3  7
5   -7  2  5 -6  4
...

上記の「関数」は数学的な意味でのみ使用していることに注意してください。入力として単一の(符号付き)整数を受け取り、単一の(符号付き)整数を返す限り、選択した言語で関数または完全なプログラムを記述できます。いつものように、STDIN、コマンドライン引数、関数引数などを介して入力を受け取り、STDOUT、関数戻り値または関数(out)引数などを介して出力を受け取ることができます。

もちろん、多くの言語は任意精度の整数を(簡単に)サポートしていません。少なくとも[-127、127]の範囲をカバーし、言語の整数型が任意に置き換えられた場合に任意の整数で機能する限り、実装が言語のネイティブ整数型の範囲でのみ機能する場合は問題ありません精度の整数。

標準の規則が適用されます。


2
密接に関連しています。違いは小さいように見えますが、古いアプローチはどれも大幅な修正なしでは機能しないことを意味します。特に、そのチャレンジからの勝利アプローチはまったく適応できないと思います。
マーティンエンダー

「すべての長さの正確に1サイクル」、「エブリの長さの多くのサイクル」があります。これは、他と区別する唯一の違いですか?
Abr001am

@ Agawa001それは1つの違いです。もう1つは、他の課題は正の整数の関数に関するものですが、この課題はすべての整数の関数を求めることです。
マーティンエンダー

1
サイクルの定義には、nが最小であることを含める必要があると思います。それ以外の場合、長さ2のサイクルは、長さ4および6などのサイクルとしてもカウントされます。
xnor

@xnorおっと、良い点。
マーティンエンダー

回答:


2

Pyth、27 18バイト

_h?gQ0^2Q*.5@,Q-xh

説明(Pyth Qは入力整数に初期化されます):

_                       negative of (
                          (
  ?gQ0                      if Q >= 0:
      ^2Q                     2**Q
                            else:
         *.5                  half of
            @        Q          element Q (modulo list length) in
             ,                    the two element list [
              Q                     Q,
                 hQ                 ((Q plus 1)
                x  Q                 XOR Q)
               -    Q               minus Q
                                  ]
 h                        ) plus 1
                        )

これにはサイクルがあります

(-1)
(0、−2)
(1、−3、-4)
(2、−5、−7、−6)
(3、−9、−13、−11、−8)
(4、− 17、-25、-21、-15、-10)
(5、-33、-49、-41、-29、-19、-12)
(6、-65、-97、-81、-57、 −37、−23、−14)
(7、−129、−193、−161、−113、−73、−45、−27、−16)
(8、−257、−385、−321、−225 、-145、-89、-53、-31、-18)
(9、-513、-769、-641、-449、-289、-177、-105、-61、-35、-20)

長さのサイクルnがで与えられます。

n − 2、
−2 ^(n − 2)⋅1− 1、
−2 ^(n − 3)⋅3− 1、
−2 ^(n − 4)⋅5− 1、
…、
−2 ^ 2 ⋅(2・n − 7)− 1、
−2 ^1⋅(2・n − 5)− 1、
−2 ^0⋅(2・n − 3)− 1)。

各整数kが ≥-1(の最初の要素として表示され、K + 2)-cycle。各整数をK <-1、我々は一意に1を書き込むことができる- Kが = 2 ^ I ⋅(2⋅ J + 1)いくつかのために、IJ ≥0。その後、kは(i + j + 2)-cycle の(j + 2)番目の要素として現れます。


5

MATL、47バイト

E|G0<-QXJ:tQ*2/0hStJ<f0))Q2MQ)&:J6M-)2/ttk>Eq*k

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

一般的な説明

以下の機能2は、関連する課題に対する@ Sp3000の回答で使用されているものと同じです。気づいてくれた@ Agawa001に感謝します。

機能は3つの構成です。

  1. Z(整数)からN(自然)への全単射。
  2. 希望する特性(各長さの1サイクル)を使用したNからNへの全単射。
  3. 関数の逆1。

関数1と3が使用されるのは、ZよりもNで目的の動作を実現する方が簡単だと思うからです。

機能2は次のとおりです。上の行はドメイン、下の行はコドメインです。明確にするためにカンマが使用されます。

1,  2  3,  4  5  6,  7  8  9  10  ...
1,  3  2,  6  4  5, 10  7  8   9  ...

最初のブロック(上1から下1)は長さ1のサイクルです。2番目(から2 3to 3 2)は長さ2のサイクルなどです。各ブロックの下部(関数のイメージ)は循環的にシフトした上部です。右に一歩。

機能1は次のとおりです。

 -5  -4  -3  -2  -1   0  +1  +2  +3  +4  ...
+10  +8  +6  +4  +2  +1  +3  +5  +7  +9  ...

機能3は1と同じで、2行が入れ替わっています。

の画像は3です-5。最初37関数1によってマップされます。次に、関数2によって7マップさ10れます。次に10、関数3によって-5`にマッピングされます。

長さ1のサイクルは0です。長さ2のサイクルは-1 1です。長さ3のサイクルは-3 2 -2などです。

コードの説明

機能1と3は簡単です。

機能2は、対応する入力ブロックの下端を見つけることによって機能します。たとえば、この関数への入力が9見つかった場合7(上記のブロックを参照)。次に10、例にある上位のエンドポイントを選択します。ブロックの循環シフトは、MATLの1ベースのモジュラーインデックス作成のおかげで実現しています。

         % FUNCTION 1
         % Implicit input
E|       % Multiply by two. Absolute value
G0<      % 1 if input is negative, 0 otherwise
-        % Subtract
Q        % Add 1
XJ       % Copy to clipboard J. Used as input to the next function

         % FUNCTION 2
:        % Range [1 2 ... J], where J denotes the input to this function
tQ*      % Duplicate, increment by 1, multiply
2/       % Divide by 2
0hS      % Prepend a 0. This is needed in case J is 0
tJ<f     % Duplicate. Find indices that are less than the input J
0)       % Pick the last index.
)        % Apply as index to obtain input value that ends previous block
Q        % Add 1: start of current block
2M       % Push the two arguments to second-to-last function call
Q)       % Add 1 and use as index: end of current block
&:       % Inclusive binary range: generate input block 
J        % Push J (input to function 2)
6M-      % Subtract start of block
)        % Apply as index (1-based, modular). This realizes the shifting

         % FUNCTION 3
2/       % Divide by 2
ttk>     % Duplicate. 1 if decimal part is not 0; 0 otherwise
Eq       % Multiply by 2, add 1
*        % Multiply
k        % Round down
         % Implicit display

これはsp3000の機能のねじれです。
-Abr001am

@ Agawa001ああ?私は他の挑戦を見ませんでした。見てみましょう
ルイスメンドー

ああ。間違いなくそうです。少なくともそれは、私の推論が、オリジナルではないとしても正しいことを明確にします:-)
ルイスメンドー

密接なアイデアを発散させるために、複数のマインドがどのように密接にフレーム化されているかは驚くべきことです。
Abr001am

4

Python 2、55バイト

g=lambda n,k=1:n/k and~g(~n+k*(n>0),k+1)+k*(n>0)or-~n%k

59バイト:

g=lambda n,k=1:n<0and~g(~n,2)or n/k and k+g(n-k,k+2)or-~n%k

サイクルを作成します

[0]
[-1, -2]
[1, 2, 3]
[-3, -4, -5, -6]
[4, 5, 6, 7, 8]
...

Sp3000の構造から変更された、以前の課題に関する私のソリューションから変更されました

関数

g=lambda n,k=1:n/k and k+g(n-k,k+2)or-~n%k

負でない数の奇数サイズのサイクルを作成します

[0]
[1, 2, 3]
[4, 5, 6, 7, 8]
...

正しいサイクルサイズを見つけるには、結果が間隔に入るまでk入力をn下にシフトk=1,3,5,7,...します[0,k)。この間隔を操作n->(n+1)%kで繰り返し、入力に対して行われたすべての減算を元に戻します。これはによって再帰的に実装されk+g(n-k,k+2)ます。

今、私たちは偶数サイクルを作るために否定を必要とします。in でg始まるように変更するとk=2g偶数サイズのサイクルが得られることに注意してください

[0, 1]
[2, 3, 4, 5]
[6, 7, 8, 9, 10, 11]
...

これらはbit-complementを介してネガティブになり~ます。したがって、when nが負の場合、単にg(n)として評価され~g(~n,2)ます。


それが役立つかどうかはわかりませんが、別の計算方法がkそうMath.floor(Math.sqrt(n))*2+1です。
ニール

@Neil私は境界とサイクルサイズを算術的に決定し、そのように計算全体を行うことも検討しましたが、これらの式はPythonで長く、再帰が短いことがわかりました。
xnor

3

Python 3、110バイト

私はまだそこにラムダを取得する方法を理解していません

nが三角形番号[1,3,6,10,15,21,28など]の場合、f(n)はリスト内の順序に負の1を掛けたものです。数値が負の場合、1 +次に小さい三角形の数値を指定します。それ以外の場合、インクリメント。

例:5は三角形の数字ではないため、1を追加します。

次の反復では、6があります。6は三角形の番号であり、リストの3番目であるため、-3になります。

プログラムはこれらのリストを提供します

長さ1:[0]

長さ2:[1、-1]

長さ3:[2,3、-2]

長さ4:[4,5,6、-3]

長さ5:[7,8,9,10、-4]

x=int(input())
if x<0:print((x**2+x)/2+1)
else:
 a=((8*x+1)**.5-1)/2
 if a%1:print(x+1)
 else:print(-a)

編集:余分な文字を削除してくれた@TuukkaXに再び感謝します。


1
あなたは、変更される可能性0.5.5してinput('')までinput()
Yytsi

2

Python 3、146バイト

0より大きいすべての数に対して、偶数ループ(len 2,4,6,8 ...)があり、0より小さい奇数ループ(1,3,5,7)があります。0は0にマッピングされます。

(-3、-2、-1)、(0)、(1,2)、(3,4,5,6)

にマップ

(-2、-1、-3)、(0)、(2,1)、(6,3,4,5)

f=lambda x:1+2*int(abs(x)**.5)if x<1 else 2*int(x**.5+.5)
x=int(input());n=f(x)
if x>0:b=n*(n-2)/4
else:b=-((n+1)/2)**2
print(b+1+(x-b-2)%n)

編集:@TuukkaXは以前のソリューションから8バイトを取り出しました。そしてさらに3。


1
最初の行のifステートメントの前に空白を削除できると思います。またmi、などの小さなものに変更することもできますb
Yytsi

以下は同じプログラムですf=lambda x:1+2*int(abs(x)**0.5)if x<1 else 2*int(x**0.5+0.5) x=int(input()) n=f(x) if x>0:b=n*(n-2)/4 else:b=-((n+1)/2)**2 print(b+1+(x-b-2)%n)
。– Yytsi

1
ありがとう、@TuukkaX。2文字の変数 'mi'を忘れていました。
マゼンタ

1
私もに変更input('')しましたinput()。入力を取得するだけの場合はコンソールに何も出力する必要がないため、引用符は役に立ちません。
-Yytsi

1
さらに短く。ドットの前のゼロを削除しました。f=lambda x:1+2*int(abs(x)**.5)if x<1 else 2*int(x**.5+.5) x=int(input());n=f(x) if x>0:b=n*(n-2)/4 else:b=-((n+1)/2)**2 print(b+1+(x-b-2)%n)
Yytsi

2

Matlab(423)

function u=f(n),if(~n)u=n;else,x=abs(n);y=factor(x);for o=1:nnz(y),e=prod(nchoosek(y,o)',1);a=log(x)./log(e);b=find(a-fix(a)<exp(-9),1);if ~isempty(b),k=e(b);l=fix(a(b));break;end;end,if(abs(n)==1)k=2;l=0;end,if(k==2)l=l+1;x=x*2;end,e=dec2base(l,k)-48;o=xor(e,circshift(e,[0 1]));g=~o(end);if(~o|nnz(o==1)~=numel(e)-g),u=n*k;else,if((-1)^g==sign(n)),u=sign(n)*k^(base2dec([e(2:end-1) 1]+48,k)-(k==2));else,u=n*k;end,end,end
  • 競合していないのは、それが最後のランキングの候補者であるという良い記録を破る一方で、できるだけ短くするのに苦労しているからです。

  • matlabの精度に関するいくつかの無意味なバグは、コードを皮肉っぽく大きくすること以外は解決できませんでしたが、一方で、私が選択するマッピングは素数とn進対数の観点からでした。

実行

 f(2)

 1

 f(1)

 2

 f(-2)

 -4

 f(-4)

 -8

 f(-8)

 -1

 f(0)

 0



 ----------------------------

説明

  • 最初に、N=e1^x1*e2^x2...この基数からの素数の指数の積として任意の数を書くことができることを知って、CNが完全なべき乗である最小因子(必ずしも素数ではない)の最大指数から抽出されたサイクルのイメージをマップすることを選択した。

  • 簡単な言葉でN=P^x、Pが最小の完全根でありx、サイクルの正確に2つの本質的な用語を示します:x=Ʃ(r*P^i)Pはサイクルのベースであり、主数Nの完全根であり、ここでkサイクルの程度です1とkの間で変化し、係数は1ずつ増加し、すべての係数がr = 1に設定されるまで、後続のプリイメージのP-1によって制限されるため、そのサイクルの開始点に移動します。C=p^kir

  • むしろ彼らの製品よりも、サイクル間の衝突に素数の累乗の選択を回避するためにために2つの塩基のサイクルの一例として、正確である32、それらの間のmeetpointができ3*2サイクルを超え、その程度によって定義されているので、これは回避されるように、そのbase、およびmeetpointには、base 6とdegree 1の別のサイクルがあります。

  • 負の数には例外があります。それについては、負の数には奇数度を、残りには偶数度を予約しました。どうして ?

    (p = 2)シーケンスがバイナリベースでなければならない場合、この点を明確にするために、サイクル内に埋め込まれた任意の数Nに対してP^k、はとして記述されP^(a0*P^i0+a1*P^i1+...)、量(a0*P^i0+a1*P^i1+...)はP-aryベースで変換されa0,a1,....ます。正/負の度数と(+/- 1)例外の条件を設定せずに事前に知られているように、数Nはk、シーケンスAがすべての塩基として、1111..{k+1}..10または111..{k}..1すべての塩基について書かれている場合にのみ、度のサイクルの端にあります回転は必要ないため、k/k'両方のそれぞれの奇数/偶数度に負/正の条件を割り当てると、奇数シーケンスが形式101..{k}..100で書き込まれ、偶数シーケンスが101..{k'}..10それぞれ負/正の数値サイクルの開始エッジの形式で書き込まれます。

    例:

    数をとるN=2^10x=10=2^1+2^3配列Aが書き込まれA=1010、シーケンスのこのタイプは正の数サイクル、有限のエッジをsymptomizes C=2^3次の画像がそのエッジ開始であるので、A=011である8しかし、この結果をstandarizingすることにより、(+ / -)1個の例外が2^10/2マップさ8/2れ、前のイメージは回転されません。

    数値を取るN=-3^9x=9=3^2、Aが書き込まれる配列はA=100、配列のこのタイプである、負の数サイクルの有限のエッジをsymptomizes C=3^1次の画像のエッジ開始のことであるように、A=01ある3負/正にこの結果を適応させることによって、しかし条件はに-3^9マップされ-3ます。

  • カップルのために(-/+)1、私2は循環基の通常のシーケンスが{2,4}{8,16,32,64}..別の形{1,2}{4,8,16,32}..で構成されていることを装って、サイクルベースの数内でそれを侵入することを想定している新しい要素


結果:

この小さなコードシートを実行して、巡回数の最初の合理的な範囲を検証します。

for (i=1:6) 
index=1;if(max(factor(i))>=5) index=0;end
for ind=0:index
j=f(((-1)^ind)*i); while(((-1)^ind)*i~=j)fprintf('%d ',j);j=f(j);end,fprintf('%d \n',(-1)^ind*i),pause,end,
end

これはこの結果につながります

 2 1 
 -2 -4 -8 -1 
 1 2 
 -4 -8 -1 -2 
 9 27 3 
 -9 -27 -81 -243 -729 -2187 -6561 -19683 -3 
 8 16 32 64 128 256 512 4 
 -8 -1 -2 -4 
 25 125 625 3125 5 
 36 216 1296 7776 46656 6 
 -36 -216 -1296 -7776 -46656 -279936 -1679616 -10077696 -60466176 -362797056 -2.176782e+009 -1.306069e+010 ??? Error using ==> factor at 27

最後はセグメンテーションエラーですが、[-127,127]標準の符号付き整数の範囲に適合します。


私はしばらく前にこの手法を使用して、私の古いCプログラムでハッシュ関数を定義しました。
Abr001am

0

JavaScript(ES6)、73バイト

f=(n,i=0,j=0,k=0,l=1,m=i<0?-i:~i)=>n-i?f(n,m,k++?j:i,k%=l,l+!k):++k-l?m:j

シーケンスを列挙することで機能します(0、-1、1、-2、2、-3、3、...)ni現在のエントリが含まれています。j現在のサイクルの開始k、サイクル内のインデックスl、現在のサイクルの長さm、シーケンスの次のエントリが含まれます。私たちが見つかったらn、我々はそれから取るj、我々はサイクルの終わりか、ならmない場合。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.