シャッフルの数


18

リフルシャッフルはシャッフルの一種で、デッキが2つのパーティションに分割された後、パーティションがスプライスされて新しいシャッフルデッキが作成されます。

カードは、カードがメンバーであるパー​​ティション内で相対的な順序を維持するように接続されます。たとえば、カードAがデッキのカードBの前にあり、カードABが同じパーティションにある場合、カードAが最終結果のカードBの前にある必要があります。場合はABが異なるパーティションにある、彼らは最終的な結果に関係なく、自分の順番の、任意の順序にすることができます。

各リフルシャッフルは、カードの元のデッキの順列として見ることができます。たとえば、順列

1,2,3 -> 1,3,2

リフルシャッフルです。このようにデッキを分割すると

1, 2 | 3

のすべてのカード1,3,2は、パーティション内の他のすべてのカードと同じ相対的な順序を持っていることがわかります。 2まだ後1です。

一方、次の順列はリフルシャッフルではありません

1,2,3 -> 3,2,1

これは、2つの(重要な)パーティションすべてに対して

1, 2 | 3
1 | 2, 3 

相対的な順序を維持しないカードのペアがあります。最初のパーティション12順序を変更し、2番目のパーティション23順序を変更します。

ただし3, 2, 1、2つのリッフルシャッフルを作成することで作成できることがわかります。

1, 3, 2 + 2, 3, 1 = 3, 2, 1

実際、証明すべき非常に単純な事実は、いくつかのリフルシャッフル順列を組み合わせて順列を作成できることです。

仕事

あなたの仕事は、入力として(サイズNの)順列を取り、入力順列を形成するために組み合わせることができる(サイズNの)最小数のリフルシャッフル順列を出力するプログラムまたは関数を作成することです。リッフルシャッフル自体を出力する必要はありません。

これはため、回答はバイト単位でスコアリングされ、バイト数は少ない方が良いでしょう。

恒等置換の場合、1または0を出力できます。

テストケース

1,3,2 -> 1
3,2,1 -> 2
3,1,2,4 -> 1
2,3,4,1 -> 1
4,3,2,1 -> 2

3
それで、RiffleSortアルゴリズムはすぐに登場するでしょうか?
mbomb007

するべきでは4,3,2,1ない2?まず、中・ゲインで分割3,1,4,2し、我々は再び中央で分割され、同じ順列を使用
Halvardフンメル

@HalvardHummelそれは正しいです。参照実装の問題を見つける必要があります。
小麦ウィザード

回答:


2

Python 3、255バイト

リストの長さまで必要なすべてのリフルをチェックします(必要な最大数)。したがって、入力が大きい場合は非常に遅くなります。また、おそらくかなりのゴルフをすることができます。

lambda x:f(range(1,len(x)+1),x)
f=lambda x,y,i=0:x==y and i or i<len(x)and min(f(q,y,i+1)for a in range(1,len(x))for q in g(x[:a],x[a:]))or i
g=lambda x,y:(x or y)and[[v]+q for v in x[:1]for q in g(x[1:],y)]+[[v]+q for v in y[:1]for q in g(x,y[1:])]or[[]]

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


2

クリーン206 ... 185バイト

import StdEnv
f=flatten
$a b#[c:d]=b
|a>[]#[u:v]=a
=[a++b,b++a:f[[[u,c:e],[c,u:e]]\\e<- $v d]]=[b]
@l#i=length l
=hd[n\\n<-[0..],e<-iter n(f o map(uncurry$o splitAt(i/2)))[[1..i]]|l==e]

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

シャッフルn時間のすべての可能な結果を​​生成し、リストがメンバーであるかどうかを確認します。
これは問題を解決するための恐ろしく非効率的な方法ですが、このコードは構成の代わりにリスト内包表記を使用しているため、特に遅くなります。

ゴルフをしていない:

import StdEnv
shuffle [] l
    = [l]
shuffle [a: b] [c: d]
    = [[a: b]++[c: d], [c: d]++[a: b]: flatten [
        [[a, c: e], [c, a: e]]
        \\ e <- shuffle b d
        ]]
numReq l
    = until cond ((+)1) 0
where
    cond n 
        = let
            mapper
                = map (uncurry shuffle o splitAt (length l/2))
            options
                = iter n (removeDup o flatten o mapper) [[1..length l]]
        in isMember l options

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

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