Các bước hoán vị


10

Viết hàm lấy một bộ số nguyên và in mọi hoán vị của tập hợp và hoán đổi được thực hiện ở giữa mỗi bước

Đầu vào

một bộ số nguyên, ví dụ (0, 1, 2)

Đầu ra

danh sách hoán vị và hoán đổi trong định dạng (bộ) (hoán đổi) (bộ) ...

Trường hợp thử nghiệm

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)

Quy tắc

  • Bạn có thể định dạng bộ số theo cách bạn muốn.
  • Bạn có thể thực hiện các giao dịch hoán đổi theo bất kỳ thứ tự nào
  • Bạn có thể lặp lại hoán vị và hoán đổi để có được một cái mới
  • Mã của bạn không thực sự phải thực hiện các giao dịch hoán đổi, đầu ra chỉ cần hiển thị hoán đổi được thực hiện giữa đầu ra cuối cùng của bạn và đầu ra hiện tại của bạn
  • Mã của bạn chỉ cần hoạt động cho các bộ có 2 phần tử trở lên
  • Tập hợp bạn đưa ra sẽ không có phần tử lặp lại (ví dụ: (0, 1, 1, 2) không hợp lệ)

Đây là mã golf, vì vậy mã ngắn nhất sẽ thắng!


Chúng ta có thể sử dụng ngẫu nhiên?
Zgarb

Bạn có nghĩa là chỉ cần thực hiện một tải các giao dịch hoán đổi ngẫu nhiên cho đến khi bạn đạt được tất cả các hoán vị? Có, nhưng bạn phải chắc chắn rằng tất cả các hoán vị đã được in
Billyoyo

3
Chào mừng đến với PPCG! Thử thách đầu tiên tốt đẹp. Tôi sẽ đề nghị chỉnh sửa ví dụ để các phần tử không bị nhầm lẫn với các chỉ mục, như sử dụng tập hợp (3, 1, 4)hoặc như vậy - đọc nó lần đầu tiên tôi đã rất bối rối vì lần hoán đổi đầu tiên hoán 0,1đổi các phần tử 0,1mà cả các chỉ số 0,1, nhưng sau đó hoán đổi không theo mô hình đó. Tôi cũng sẽ chỉ cho bạn đến Sandbox nơi bạn có thể đăng các thử thách và nhận phản hồi trước khi đăng chúng lên trang web chính.
admBorkBork

2
@TimmyD cảm ơn vì lời đề nghị, tôi đã thay đổi ví dụ. Tôi thấy liên kết đến hộp cát ngay sau khi tôi đăng bài này, tôi sẽ đăng ở đó đầu tiên kể từ bây giờ!
Billyoyo

1
Các Steinhaus-Johnson-Trotter thuật toán tạo ra các chuỗi cần thiết tối thiểu.
Neil

Câu trả lời:


3

Toán học, 102 byte

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

Ví dụ

// Cột cho kết quả rõ ràng hơn

%[{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

Java, 449 426 byte

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+")");}}

Phương pháp vũ phu. Nó tiếp tục thực hiện các giao dịch hoán đổi ngẫu nhiên cho đến khi tất cả các hoán vị có thể xảy ra. Nó sử dụng Tập hợp biểu diễn chuỗi của mảng để kiểm tra có bao nhiêu trạng thái khác nhau đã được tạo. Đối với n số nguyên khác nhau có n! = 1 * 2 * 3 * .. * n hoán vị riêng biệt.

Cập nhật

  • Thực hiện theo đề xuất của Kevin Cruijssen để đánh gôn thêm một chút.

Ung dung:

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 + ")");
    }
}

Sử dụng:

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

Như bạn có thể thấy có nhiều giao dịch hoán đổi hơn mức tối thiểu cần thiết. Nhưng nó có vẻ hoạt động :-D

Như một phần thưởng, nó cũng hoạt động với các chuỗi, tức là

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

Bạn có phiên bản chưa chơi golf nào để chúng tôi xem xét phương pháp của bạn bằng cách sử dụng không?
Billyoyo

@Billyoyo: Đã thêm mã không chơi gôn. Tuy nhiên, không có gì lạ mắt ở đó :-)
Master_ex

Bạn có thể chơi golf một chút. Không cần sửa cảnh báo, vì vậy bạn có thể xóa khai báo Set : Set s=new HashSet();. Mã của bạn trong phương thức ncó thể là một trả về duy nhất : static int n(int x){return x==1?1:x*n(x-1);}. Và bạn có thể thay thế String ztrong phương thức của bạn obằng một cái chung thay thế : static<T>void o(T z){System.out.println(z);s.add(z);}. Tất cả kết hợp lại sẽ giảm xuống còn 426 byte .
Kevin Cruijssen

1

JavaScript (ES6), 186 byte

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`,`)>

Lưu ý: Tôi không chắc định dạng đầu ra linh hoạt đến mức nào, có thể tôi có thể làm điều này với 171 byte:

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}

Hoạt động bằng cách thực hiện thuật toán Steinhaus gay Johnson Nhận Trotter trên mảng xáo trộn các chỉ số và dịch trở lại mảng đầu vào. Ung dung:

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

Ruby, 86 byte

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

1

Haskell - 135 byte

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

đầu ra:

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

Tôi đang sử dụng permutationshàm tiêu chuẩn , không dựa trên các giao dịch hoán đổi, vì vậy tôi đang sử dụng các hoán vị của hoán vị và tìm một hàm xảy ra là một chuỗi các giao dịch hoán đổi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.