Cuantos barajos

18

Un aleatorio aleatorio es un tipo de aleatorio donde el mazo se divide en dos particiones y las particiones se vuelven a unir para crear un nuevo mazo barajado.

Las tarjetas se unen de tal manera que las tarjetas mantienen su orden relativo dentro de la partición de la que son miembros . Por ejemplo, si la carta A está antes de la carta B en el mazo y las cartas A y B están en la misma partición, la carta A debe estar antes de la carta B en el resultado final, incluso si el número de cartas entre ellas ha aumentado. Si A y B están en particiones diferentes, pueden estar en cualquier orden, independientemente de su orden inicial, en el resultado final.

Cada riffle shuffle se puede ver como una permutación del mazo de cartas original. Por ejemplo la permutación

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

es un riffle shuffle Si divides la baraja así

1, 2 | 3

vemos que cada tarjeta 1,3,2tiene el mismo orden relativo que todas las demás tarjetas de su partición. 2Todavía está después 1.

Por otro lado, la siguiente permutación no es un riffle shuffle.

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

Podemos ver esto porque para las dos particiones (no triviales)

1, 2 | 3
1 | 2, 3 

Hay un par de cartas que no mantienen su orden relativo. En la primera partición 1y 2cambiar su orden, mientras que en la segunda partición 2y 3cambiar su orden.

Sin embargo, vemos que 3, 2, 1se puede hacer componiendo dos barajaduras,

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

De hecho, un hecho bastante simple para ser probado es que cualquier permutación puede hacerse combinando un cierto número de permutaciones de riffle shuffle.

Tarea

Su tarea es hacer un programa o función que tome una permutación (de tamaño N ) como entrada y genere el menor número de permutaciones de riffle shuffle (de tamaño N ) que se pueden combinar para formar la permutación de entrada. No es necesario que el riffle baraje por sí mismo cuántos hay.

Este es el por lo que las respuestas se puntuarán en bytes con menos bytes mejor.

Puede generar 1 o 0 para una permutación de identidad.

Casos de prueba

1,3,2 -> 1
3,2,1 -> 2
3,1,2,4 -> 1
2,3,4,1 -> 1
4,3,2,1 -> 2
Asistente de trigo
fuente
3
Entonces, ¿veremos algoritmos RiffleSort pronto?
mbomb007
No debe 4,3,2,1ser 2? Primero nos dividimos en el medio y 3,1,4,2ganamos y luego nos dividimos en el medio nuevamente y usamos la misma permutación
Halvard Hummel el
@HalvardHummel Eso es correcto. Tendré que encontrar el problema con mi implementación de referencia.
Wheat Wizard

Respuestas:

2

Python 3 , 255 bytes

Comprueba todos los riffs posibles hasta la longitud de la lista (se requiere el número máximo), por lo que es muy lento para entradas más grandes. Probablemente también se pueda jugar bastante al 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[[]]

Pruébalo en línea!

Halvard Hummel
fuente
2

Limpio , 206 ... 185 bytes

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]

Pruébalo en línea!

Genera todos los resultados posibles de los ntiempos de mezcla y verifica si la lista es miembro.
Si bien esta es una forma terriblemente ineficiente de resolver el problema, este código es particularmente lento debido a su uso de listas de comprensión en lugar de composición, lo que limita en gran medida cualquier reducción de gráfico elemental, y da como resultado una espectacular exhibición del recolector de basura de Clean.

Sin golf:

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

Pruébalo en línea!

Οurous
fuente