Kaç karışık


18

Bir riffle shuffle, desteğin iki bölüme ayrıldığı ve daha sonra bölümlerin yeni bir karıştırılmış güverte oluşturmak için tekrar birleştirildiği bir tür shuffle'dır.

Kartlar, üyesi oldukları bölüm içinde göreceli sıralarını koruyacak şekilde birbirine eklenir . Örneğin, A kartı destedeki B kartından önce ve A ve B kartları aynı bölümdeyse, aralarındaki kart sayısı artmış olsa bile A kartı nihai sonuçtaki B kartından önce olmalıdır . Eğer A ve B farklı bölümlere, onlar nihai sonuçta ne olursa olsun başlangıç düzenin, herhangi bir sırada olabilir.

Her bir tüfek karıştırması, orijinal kart destesinin permütasyonu olarak görülebilir. Örneğin permütasyon

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

bir tüfek shuffle. Eğer güverteyi böyle ayırırsan

1, 2 | 3

içerisindeki her kartın, 1,3,2bölümündeki diğer tüm kartlarla aynı göreli sıraya sahip olduğunu görüyoruz . 2hala peşinde 1.

Öte yandan, aşağıdaki permütasyon fırfırlı bir karıştırma değildir .

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

Bunu görebiliriz çünkü iki (önemsiz) bölümün tümü için

1, 2 | 3
1 | 2, 3 

göreceli sıralamalarını yerine getirmeyen bir çift kart vardır. İlk bölümde 1ve 2sıralarını değiştirirken, ikinci bölümde 2ve 3sıralarını değiştir.

Ancak bunun 3, 2, 1iki tüfek karıştırmasıyla yapılabileceğini görüyoruz ,

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

Aslında kanıtlanması oldukça basit bir gerçek, bir dizi tüfek shuffle permütasyonunu birleştirerek herhangi bir permütasyon yapılabileceğidir.

Görev

Göreviniz, bir permütasyonu ( N boyutunda ) giriş olarak alan ve giriş permütasyonunu oluşturmak için birleştirilebilen en az sayıda tüfek shuffle permütasyonunu ( N boyutunda ) çıkaran bir program veya işlev yapmaktır . Kaç tane riffle karıştırdığını kendiniz çıkarmanız gerekmez.

Bu bu nedenle cevaplar daha az bayt daha iyi olacak şekilde bayt cinsinden puanlanır.

Kimlik permütasyonu için 1 veya 0 çıktısı alabilirsiniz.

Test Durumları

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

3
Peki, yakında RiffleSort algoritmalarını görecek miyiz?
mbomb007

Gerekmiyor 4,3,2,1olmak 2? Önce ortadan ayrıldık ve kazandık 3,1,4,2, sonra tekrar ortadan ayrıldık ve aynı permütasyonu kullanıyoruz
Halvard Hummel

@HalvardHummel Doğru. Referans uygulamamla ilgili sorunu bulmam gerekecek.
Post Rock Garf Hunter

Yanıtlar:


2

Python 3 , 255 bayt

Listenin uzunluğuna kadar tüm olası riffleri kontrol eder (maksimum sayı gerekir), bu nedenle daha büyük girişler için çok yavaştır. Ayrıca muhtemelen biraz golfed olabilir.

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

Çevrimiçi deneyin!


2

Temiz , 206 ... 185 bayt

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]

Çevrimiçi deneyin!

Karıştırma nsürelerinin olası her sonucunu oluşturur ve listenin üye olup olmadığını kontrol eder.
Bu sorunu çözmek için çok verimsiz bir yol olsa da, bu kod herhangi bir temel grafik azalmasını büyük ölçüde sınırlayan ve Clean'in çöp toplayıcısının muhteşem bir vitrine neden olan kompozisyon yerine liste kavrayışlarının kullanılması nedeniyle özellikle yavaştır .

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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.