Quanti shuffles


18

Un riffle shuffle è un tipo di shuffle in cui il mazzo viene diviso in due partizioni e le partizioni vengono quindi ricucite insieme per creare un nuovo mazzo mischiato.

Le carte sono unite insieme in modo tale che le carte mantengano il loro ordine relativo all'interno della partizione di cui fanno parte . Ad esempio, se la carta A è prima della carta B nel mazzo e le carte A e B si trovano nella stessa partizione, la carta A deve trovarsi prima della carta B nel risultato finale, anche se il numero di carte tra loro è aumentato. Se A e B si trovano in partizioni diverse, possono essere in qualsiasi ordine, indipendentemente dal loro ordine di partenza, nel risultato finale.

Ogni shuffle di riffle può quindi essere visto come una permutazione del mazzo di carte originale. Ad esempio la permutazione

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

è un riffle shuffle. Se dividi il mazzo in questo modo

1, 2 | 3

vediamo che ogni carta in 1,3,2ha lo stesso ordine relativo ad ogni altra carta nella sua partizione. 2è ancora dopo 1.

D'altra parte la seguente permutazione non è un riordino di riffle.

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

Possiamo vederlo perché per tutte e due le partizioni (non banali)

1, 2 | 3
1 | 2, 3 

c'è una coppia di carte che non mantiene i relativi ordini. Nella prima partizione 1e 2modifica il loro ordine, mentre nella seconda partizione 2e 3modifica il loro ordine.

Comunque vediamo che 3, 2, 1può essere realizzato componendo due shuffle di riffle,

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

In effetti un fatto piuttosto semplice da dimostrare è che ogni permutazione può essere fatta combinando un certo numero di permutazioni di shuffle del riffle.

Compito

Il tuo compito è creare un programma o una funzione che accetta una permutazione (di dimensione N ) come input e genera il minor numero di permutazioni di shuffle riffle (di dimensione N ) che possono essere combinate per formare la permutazione di input. Non è necessario emettere i riffle mescolando loro stessi quanti ce ne siano.

Si tratta di quindi le risposte verranno classificate in byte con un numero inferiore di byte migliori.

È possibile generare 1 o 0 per una permutazione dell'identità.

Casi test

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

3
Quindi vedremo presto gli algoritmi RiffleSort?
mbomb007,

Non dovrebbe 4,3,2,1essere 2? Prima ci dividiamo nel mezzo e guadagniamo 3,1,4,2e poi ci dividiamo di nuovo nel mezzo e usiamo la stessa permutazione
Halvard Hummel

@HalvardHummel È corretto. Dovrò trovare il problema con la mia implementazione di riferimento.
Wheat Wizard

Risposte:


2

Python 3 , 255 byte

Controlla tutti i possibili riffle fino alla lunghezza dell'elenco (numero massimo richiesto), quindi è molto lento per input più grandi. Probabilmente potrebbe anche essere giocato un po 'a golf.

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[[]]

Provalo online!


2

Pulito , 206 ... 185 byte

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]

Provalo online!

Genera tutti i possibili risultati dei ntempi di mescolamento e controlla se l'elenco è un membro.
Mentre questo è un modo orribilmente inefficiente per risolvere il problema, questo codice è particolarmente lento a causa del suo uso della comprensione dell'elenco anziché della composizione, che limita fortemente qualsiasi riduzione elementare del grafico e si traduce in una spettacolare vetrina del garbage collector di Clean.

Ungolfed:

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

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.