あらゆるサイズのデッキのパーフェクトシャッフルのサイクル長


10

チャレンジ

最短のコードで:

  1. 任意のサイズのカードのデッキ上に完全シャッフルの順列サイクルの長さを計算し、NN ≥2及びnは偶数です)。
  2. 出力2≤のためのすべてのサイクルの長さのテーブルN ≤1000(nは偶数)。

完璧なシャッフルを定義するには、2つの基本的な方法があることに注意してください。あり、アウトシャッフル上に最初のカードと下部に最後のカードを保持し、かつそこにある中、シャッフル中央に向かって、最初と最後のカード1点の位置を移動し、。シャッフルするかシャッフルするかを選択できます。アルゴリズムは2つの間でほとんど同じです。

  • 10カードデッキのシャッフル:[1,2,3,4,5,6,7,8,9,10]↦[1,6,2,7,3,8,4,9,5、 10]。
  • 10カードデッキのシャッフル:[1,2,3,4,5,6,7,8,9,10]↦[6,1,7,2,8,3,9,4,10、 5]。

グラフィカルな例

ここでは、20カードデッキのアウトシャッフルのサイクル長が18ステップであることがわかります。(これは説明のみを目的としています。サイクルをグラフィカルに出力するためのソリューションは必要ありません。)一方、クラシック52カードデッキは、8段のアウトシャッフルサイクル長しかありません(図には示されていません)。

20カードデッキのアウトシャッフルサイクル

インシャッフル 20枚のカードデッキには、6つのステップのサイクル長を有しています。

20カードデッキのシャッフルサイクル

出力の表形式の例

プログラムはこれに似たものを出力するはずですが、好きな表形式を選択することもできます。これはアウトシャッフル用です:

2 1
4 2
6 4
8 3
10 6
12 10
14 12
16 4
18 8
20 18
22 6
24 11
26 20
28 18
30 28
32 5
34 10
36 12
38 36
40 12
...many lines omitted...
1000 36

ご質問

  1. nが2の累乗である場合、数値入力nとそのサイクルカウントの間に何らかの関係があるように見えますか?
  2. nが2の累乗でない場合はどうでしょうか?
  3. 奇妙なことに、1000枚のカードデッキのアウトシャッフルサイクルカウントは36のみですが、500枚のカードデッキのアウトシャッフルサイクルカウントは166です。なぜでしょうか。
  4. サイクルカウントcnよりも大幅に小さい、つまり比率n / cが最大になる、あなたが見つけることができる最大の数は何ですか?


でも、それは結果を表示することの詳細です。この質問は、任意のn値のテーブルを生成することに関するものです。それは本質的により数学的です。
トッドリーマン

しばらくの間、デモの6/8サイクルと混乱しました:)(私の実装が間違っていると思いました)。最後に画像を見て、それが6サイクルであることを確認したので、編集しました。おかしい
誇り高いハスケラー

@proud haskeller —ああそう、ありがとう!
Todd Lehman

1
これはシーケンスA002326です。
orlp 2015

回答:


6

Haskell、47 46 44(シャッフルで)

[[i|i<-[1..],mod(2^i)n<2]!!0|n<-[3,5..1001]]

基本的な認識は、これは係数の乗法グループの2の次数であるということですn+1


1
あなたは削除することができますl=-式自体で十分です。対話型のコマンドラインで実行すると、これは有効なプログラムです。
orlp 2015


2

Pyth、22バイト

V500,JyhNl{.u.iFc2NJUJ

オンラインで試す:デモ。遅すぎる場合は、500を小さい数値に置き換えます。

説明:

V500                     for N in [0, 1, ..., 499]:
      yhN                   (N + 1) * 2
     J                      assign to J
           .u      JUJ      apply the following expression J times
                            to N, starting with N = [0, 1, ..., J - 1],
                            and return all intermediate results:
                c2N            split N into 2 halfs
             .iF               and interleave them
         l{                 remove duplicates and give length
    ,                       make a pair and print

1
デッキをシャッフルして数えるという実際の作業を行うpythソリューションが、簡単な式を使用するhaskellソリューションが結果を即座に予測する限り、半分だけであるというのはちょっとおかしい
Falco

@Falco私は正しく知っています
誇り高いhaskeller、2015

1
@Falco私は実際に私の答えのpythポートを実行しようとしましたが、それを行う方法を理解できませんでした。だから私はちょうど
誇りに思っているハスケラー

<> <を試さなかったことをうれしく思います
Falco

2

Mathematica、53(入れ替え)

Grid[{2#,MultiplicativeOrder[2,2#+1]}&/@Range[1,500]]

または、拮抗的に配置されていない

Grid[{2 #, MultiplicativeOrder[2, 2 # + 1]} & /@ Range[1, 501]]

出力:

   2    2
   4    4
   6    3
   8    6
  10   10
  12   12
  14    4
  16    8
  18   18
  20    6
 (* digits, digits, bo bidgits, banana fana, ... *)
  498  166
  500  166
 (* skip a bit, brother ...  *)
  998   36
 1000   60

両方の列のすべてのエントリは、列の水平方向の中央に配置されますが、小数のスペースはありません&#8194;... &#8202;ここでそれを複製します。

観察:

  • アウトシャッフルは、2枚小さいカードのデッキでインシャッフルです。(最初のカードと最後のカードは、シャッフルのデモンストレーション全体で固定されていることに注意してください。)その結果、2つの選択肢は同様の出力リストにつながります。2番目の列は1行ずつシフトされます。ヒント「2の累乗」については、中・シャッフル2つのデッキの電源のパターンを持っています{2^n - 2, n}{2^n, 2n}。(。でペア2^nをアウトシャッフルしnます。)
  • シャッフル内の例で2は、デッキの最も近い端からの距離が各ステップで2倍になることを確認します。 {2, 4, 8, 15 = -5, -10, -20}。実際、これはすべてのカードに当てはまります。したがって、どのパワーがmod に2合同で、どこがカードの数であるかを知る必要があるだけです。(なお、実施例では、最後の列のカード、カラム、最後から二番目の列に倍増され、意味したがって、「MOD、デッキにあるよりも1枚の以上のカードと合同である」。)したがって、MultiplicativeOrder []関数は、(Mathematicaで)進むべき道です。1n+1n-1-20n+1
  • デフォルトでは、Grid []ではなくTableForm []を試しますが、出力は同様です。

あなたの出力例は間違っているようです
誇り高いhaskeller '

@proudhaskeller:シャッフルまたはアウトシャッフルの場合?どちらでもかまいません。(そして、注記したように、1つはもう1つの右の列の1行のシフトにすぎません。)
Eric Towers

どちらも合わないようです。質問の出力例を調べてください。たぶんあなたの例の出力は間違っていて、実際のコードは正しいので、例は古くなっているだけかもしれません。
誇り高いHaskeller、2015

proudhaskeller:私の例の出力を「8」と入力したようです。そして、少なくとも一度は内外に混乱した。編集。粘り強くご利用いただきありがとうございます。:-)
エリックタワーズ

0

C、86(または84)

スコアは、明確にするために含まれている不要な空白を除外しています。

i,j,n;
main(){
  for(;n<1002;printf("%d %d\n",n,j),n+=2)
    for(i=n,j=1;i=i*2%(n+1),i-n;)j++;
}

これは、他の人が指摘したように、両端の固定カードが取り除かれたアウトシャッフルです。

他の人が指摘しているように、シャッフルでは、各カードの位置が毎回2倍になりますが、これはモジュロを取る必要がありますn+1。余分なカードの位置をテーブルの左側のゼロの位置と考えるのが好きです(これはアウトシャッフルから両方の固定カードを保持していると考えることもできます)。明らかに、カードの位置は常に正でなければならないため、シャッフル中の場合、ゼロの位置は常に空のままです。

コードiはの値に初期化されますn。次に、2を乗算し、結果のmod (n+1)i取得して、がその初期値(i-nゼロ)に戻ったかどうかを確認します。j最後の反復を除いて、反復ごとに増分します(したがって、初期化の必要性jは1です)。

原則として、最後の比較で同じ数値に初期化されているかどうかを確認する限りi、範囲内の任意の値を使用できます1..n。ピッキングの理由はn、プログラムがケースで機能することを確認するためでしたn==0。問題は、任意の数を法(0+1)とする数値がゼロであるため、この場合、ループiが1などの定数に初期化されている場合、ループが終了しないことです。

質問の例にはn==2アウトシャッフルの同等のケースが含まれているため、このケースが必要であると解釈されました。そうでない場合は、1にn,初期化iすることで2バイトを節約できますj。これはと同じ値です。

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