몇 셔플


18

리플 셔플은 데크가 두 개의 파티션으로 분할되고 파티션이 다시 연결되어 새로운 셔플 데크를 만드는 셔플 유형입니다.

카드는 멤버가 속한 파티션 내에서 상대 순서를 유지하는 방식으로 서로 연결됩니다 . 예를 들어, 카드 A 가 데크의 카드 B 보다 앞에 있고 카드 AB 가 동일한 파티션에있는 경우, 카드 A 는 카드 사이에 카드 수가 증가하더라도 최종 결과에서 카드 B 보다 앞에 있어야합니다 . 경우 와 B가 서로 다른 파티션에들은 최종 결과에 관계없이 시작 순서의 임의의 순서 일 수있다.

그런 다음 각 리플 셔플은 원본 카드 덱의 순열로 볼 수 있습니다. 예를 들어 순열

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

리플 셔플입니다. 이렇게 갑판을 나누면

1, 2 | 3

우리는 모든 카드 1,3,2가 파티션의 다른 모든 카드 와 동일한 상대 순서를 가지고 있음을 알 수 있습니다. 2여전히 뒤에 1있습니다.

반면에 다음 순열은 리플 셔플 이 아닙니다 .

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

두 개의 (사소하지 않은) 파티션 모두에 대해 이것을 볼 수 있습니다.

1, 2 | 3
1 | 2, 3 

상대 순서를 유지하지 않는 한 쌍의 카드가 있습니다. 첫 번째 파티션에 12있는 동안 두 번째 파티션에, 자신의 순서를 변경 2하고 3자신의 순서를 변경합니다.

그러나 우리는 3, 2, 1두 개의 리플 셔플을 구성하여 만들 수 있다는 것을 알았습니다.

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,12? 먼저 우리는 중간에서 나누고 이득을 얻은 3,1,4,2다음 중간에서 다시 나누고 같은 순열을 사용합니다
Halvard Hummel

@HalvardHummel 맞습니다. 참조 구현과 관련된 문제를 찾아야합니다.
밀 마법사

답변:


2

파이썬 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시간 의 가능한 모든 결과를 생성 하고 목록이 멤버인지 확인합니다.
이것은 문제를 해결하기 위해 끔찍한 비효율적 인 방법이지만,이 코드는 구성 대신 목록 이해를 사용하기 때문에 특히 느리 므로 모든 기본 그래프 감소를 크게 제한하고 Clean의 가비지 수집기의 화려한 쇼케이스를 만듭니다.

언 골프 드 :

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.