순열의 단계


10

정수 세트를 취하고 세트의 모든 순열을 인쇄하는 함수를 작성하고 각 단계 사이에서 스왑을 수행하십시오.

입력

정수 세트 (예 : (0, 1, 2))

산출

형식 (세트) (스왑) (세트)의 순열 및 스왑 목록 ...

테스트 사례

Input: 
(3, 1, 5)

Output:
(3, 1, 5)
(3, 1)
(1, 3, 5)
(3, 5)
(1, 5, 3)
(1, 3)
(3, 5, 1)
(3, 5)
(5, 3, 1)
(3, 1)
(5, 1, 3)

규칙

  • 원하는 숫자 세트를 포맷 할 수 있습니다.
  • 어떤 순서로든 스왑을 수행 할 수 있습니다
  • 새로운 순열을 얻기 위해 순열과 스왑을 반복 할 수 있습니다
  • 코드는 실제로 스왑을 수행 할 필요가 없으며 출력은 마지막 출력과 현재 출력 사이에 스왑이 무엇인지 보여 주기만하면됩니다.
  • 코드는 2 개 이상의 요소가있는 세트에서만 작동해야합니다.
  • 주어진 세트에는 반복되는 요소가 없습니다 (예 : (0, 1, 1, 2)가 유효하지 않습니다)

이것은 코드 골프이므로 가장 짧은 코드가 승리합니다!


우리는 무작위성을 사용할 수 있습니까?
Zgarb

모든 순열을 달성 할 때까지 임의의 스왑을로드한다는 의미입니까? 예, 그러나 모든 순열이 인쇄되었는지 확인해야합니다
Billyoyo

3
PPCG에 오신 것을 환영합니다! 좋은 첫 번째 도전. 예제를 편집하여 요소가 사용 세트와 같은 인덱스와 혼동되지 않도록 제안 (3, 1, 4)합니다. 처음 스왑 0,1이 요소 0,1와 인덱스를 교환 했기 때문에 처음 혼란 스러울 때 읽은 0,1다음 다음 스왑은 그 패턴을 따르지 않았습니다. 또한 기본 사이트에 게시하기 전에 문제를 게시하고 피드백을받을 수 있는 샌드 박스를 안내합니다.
AdmBorkBork

2
@TimmyD 제안에 감사드립니다. 예를 변경했습니다. 게시 한 직후 샌드 박스 링크를 보았습니다. 지금부터 먼저 게시하겠습니다!
Billyoyo

1
STEINHAUS - 존슨 - 트로터 알고리즘 최소 필요한 시퀀스를 생성한다.
Neil

답변:


3

수학, 102 바이트

<<Combinatorica`
Riffle[#,BlockMap[Pick[#[[1]],#!=0&/@({1,-1}.#)]&,#,2,1]]&@*MinimumChangePermutations

// 더 명확한 결과를위한 열

%[{1,3,5}]//Column
(*
{1,3,5}
{1,3}
{3,1,5}
{3,5}
{5,1,3}
{5,1}
{1,5,3}
{1,3}
{3,5,1}
{3,5}
{5,3,1}
*)

3

자바, 449 바이트

import java.util.*;interface P{static Set s=new HashSet();static void main(String[]a){o(Arrays.toString(a));while(s.size()<n(a.length)){p(a);o(Arrays.toString(a));}}static<T>void o(T z){System.out.println(z);s.add(z);}static int n(int x){return x==1?1:x*n(x-1);}static void p(String[]a){Random r=new Random();int l=a.length,j=r.nextInt(l),i=r.nextInt(l);String t=a[j];a[j]=a[i];a[i]=t;System.out.println("("+a[j]+","+t+")");}}

무차별 대입 접근. 가능한 모든 순열이 발생할 때까지 무작위로 스왑을 만듭니다. 얼마나 많은 다른 상태가 생성되었는지 확인하기 위해 배열의 문자열 표현 세트를 사용합니다. n 개의 다른 정수에는 n이 있습니다! = 1 * 2 * 3 * .. * n 뚜렷한 순열.

최신 정보

  • Kevin Cruijssen의 골프 제안에 따라 조금 더 골프를 쳤다.

언 골프 드 :

import java.util.*;

interface P {

    static Set<String> s = new HashSet<>();

    static void main(String[] a) {
        // prints the original input
        o(Arrays.toString(a));
        while (s.size() < n(a.length)) {
            p(a);
            // prints the array after the swap
            o(Arrays.toString(a));
        }
    }

    static void o(String z) {
        System.out.println(z);
        // adds the string representation of the array to the HashSet
        s.add(z);
    }

    // method that calculates n!
    static int n(int x) {
        if (x == 1) {
            return 1;
        }
        return x * n(x - 1);
    }

    // makes a random swap and prints what the swap is
    static void p(String[] a) {
        Random r = new Random();
        int l = a.length, j = r.nextInt(l), i = r.nextInt(l);
        String t = a[j];
        a[j] = a[i];
        a[i] = t;
        System.out.println("(" + a[j] + "," + t + ")");
    }
}

용법:

$ javac P.java
$ java P 1 2 3
[1, 2, 3]
(2,1)
[2, 1, 3]
(1,1)
[2, 1, 3]
(2,2)
[2, 1, 3]
(3,1)
[2, 3, 1]
(3,1)
[2, 1, 3]
(1,2)
[1, 2, 3]
(1,1)
[1, 2, 3]
(3,2)
[1, 3, 2]
(2,3)
[1, 2, 3]
(3,1)
[3, 2, 1]
(3,1)
[1, 2, 3]
(3,3)
[1, 2, 3]
(1,2)
[2, 1, 3]
(1,3)
[2, 3, 1]
(1,2)
[1, 3, 2]
(3,1)
[3, 1, 2]

보시다시피 필요한 최소값보다 더 많은 스왑이 있습니다. 그러나 작동하는 것 같습니다 : -D

보너스로 문자열과도 작동합니다.

$ java P 'one' 'two'
[one, two]
(two,one)
[two, one]

사용하는 방법을 살펴볼 수있는 골프 용 버전이 있습니까?
Billyoyo

@Billyoyo : 골프화되지 않은 코드가 추가되었습니다. 그러나 멋진 것은 없습니다 :-)
Master_ex

당신은 그것을 조금 골프 수 있습니다. 경고를 고칠 필요가 없으므로 Set 선언을 제거 할 수 있습니다 Set s=new HashSet();. 메소드의 코드 n는 단일 리턴 일 수 있습니다 static int n(int x){return x==1?1:x*n(x-1);}. 그리고 대신 String z메소드 o에서 일반으로 대체 할 수 있습니다 static<T>void o(T z){System.out.println(z);s.add(z);}. 모두 합쳐서 426 바이트줄었다 .
Kevin Cruijssen

1

자바 스크립트 (ES6), 186 바이트

f=
a=>{console.log(a);d=a.slice().fill(-1);s=[...d.keys()];for(i=l=a.length;i;)s[k=(j=s.indexOf(--i))+d[i]]<i?(console.log(a[s[j]=s[k]],a[s[k]=i]),console.log(s.map(n=>a[n])),i=l):d[i]*=-1}
;
<input id=i><input type=button value=Go! onclick=f(i.value.split`,`)>

참고 : 출력 형식이 얼마나 유연한 지 잘 모르겠습니다. 171 바이트 동안이 작업을 수행 할 수 있습니까?

a=>{console.log(a);d=a.slice().fill(-1);s=[...d.keys()];for(i=l=a.length;i;)s[k=(j=s.indexOf(--i))+d[i]]<i?console.log(a[s[j]=s[k]],a[s[k]=i],s.map(n=>a[n],i=l)):d[i]*=-1}

인덱스 순서 섞기 배열 에서 Steinhaus–Johnson–Trotter 알고리즘을 수행 하고 입력 배열로 다시 변환하여 작동합니다. 언 골프 드 :

function steps(array) {
    console.log(array); // initial row
    var d = a.slice().fill(-1); // direction values
    var s = [...a.keys()]; // initial (identity) shuffle
    var l = a.length;
    for (var i = l; i; ) { // start by trying to move the last element
        var j = s.indexOf(--i);
        var k = j + d[i]; // proposed exchange
        if (s[k] < i) { // only exchange with lower index (within bounds)
            console.log(a[s[k]],a[i]); // show values being exchanged
            s[j] = s[k];
            s[k] = i; // do the exchange on the shuffle
            console.log(s.map(n=>a[n])); // show the shuffled array
            i = l; // start from the last element again
        } else {
            d[i] *= -1; // next time, try moving it the other way
        } // --i above causes previous element to be tried
    } // until no movable elements can be found
}

1

루비, 86 바이트

puts (2..(a=gets.scan(/\d+/).uniq).size).map{|i|a.permutation(i).map{|e|?(+e*", "+?)}}

1

하스켈-135 바이트

p=permutations;f=filter
q(a:b:xs)=(\x->f(uncurry(/=)).zip x)a b:q(b:xs);q _=[]
l=head.f(all((==2).length).q).p.p
f=zip.l<*>map head.q.l

산출:

> f [3,1,5]
[([3,1,5],(3,1)),([1,3,5],(3,5)),([1,5,3],(1,5)),([5,1,3],(1,3)),([5,3,1],(5,3))]

permutations스왑을 기반으로하지 않는 표준 함수를 사용하고 있으므로 순열의 순열을 취하고 스왑 체인으로 발생하는 순열을 찾습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.