Permütasyon Adımları


10

Bir tamsayı kümesi alan ve setin her permütasyonunu ve her adım arasında gerçekleştirilen takasları basan bir fonksiyon yazın

Giriş

bir tamsayı kümesi, örneğin (0, 1, 2)

Çıktı

(set) (takas) (set) biçimindeki permütasyon ve takasların listesi ...

Test durumu

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)

kurallar

  • Sayı kümesini istediğiniz gibi biçimlendirebilirsiniz.
  • Takasları istediğiniz sırayla yapabilirsiniz
  • Yeni bir tane almak için permütasyonları ve takasları tekrarlayabilirsiniz.
  • Kodunuzun takasları gerçekten gerçekleştirmesi gerekmez, çıktının sadece son çıktınız ile mevcut kodunuz arasında hangi takasın yapıldığını göstermesi gerekir
  • Kodunuzun yalnızca 2 veya daha fazla öğeli kümeler için çalışması gerekir
  • Verdiğiniz kümede yinelenen öğeler olmayacak (ör. (0, 1, 1, 2) geçersiz)

Bu kod golf, bu yüzden en kısa kod kazanır!


Rasgelelik kullanabilir miyiz?
Zgarb

Yani tüm permütasyonlara ulaşana kadar bir sürü rastgele takas mı yapıyorsun? Evet, ancak tüm permütasyonların yazdırıldığından emin olmalısınız
Billyoyo

3
PPCG'ye Hoşgeldiniz! Güzel ilk meydan okuma. Ben elemanları kullanım seti gibi, endekslerin ile karıştırılmamalıdır alamadım bu yüzden örnek düzenleme öneririm (3, 1, 4)o ilk takas çünkü çok karıştı ilk defa okuma - bu yüzden ya 0,1unsurları takas 0,1da ancak endeksleri 0,1sonraki o zaman, ama takas bu kalıbı takip etmedi. Ben de sizi işaret edeceğiz Sandbox sen zorlukları gönderebilir ve ana siteye yayınlanmadan önce geri bildirim almak nerede.
AdmBorkBork

2
@TimmyD öneri için teşekkürler, örneği değiştirdim. Bunu gönderdikten hemen sonra kum havuzunun bağlantısını gördüm, bundan sonra oraya ilk göndereceğim!
Billyoyo

1
Steinhaus Johnson-Paça algoritması gerekli minimum diziyi üretir.
Neil

Yanıtlar:


3

Mathematica, 102 bayt

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

Örnekler

// Daha net bir sonuç için sütun

%[{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, 449426 bayt

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

Kaba kuvvet yaklaşımı. Olası tüm permütasyonlar gerçekleşene kadar rastgele takaslar yapmaya devam eder. Kaç farklı durumun üretildiğini kontrol etmek için dizinin dize olarak temsil edilen kümesini kullanır. N farklı tamsayı için n vardır! = 1 * 2 * 3 * .. * n farklı permütasyon.

Güncelleme

  • Kevin Cruijssen'in biraz daha golf önerilerini takip etti.

Ungolfed:

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

Kullanımı:

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

Gördüğünüz gibi gerekli minimumdan çok daha fazla takas var. Ama işe yarıyor gibi görünüyor :-D

Bonus olarak, dizelerle de çalışır, yani

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

Kullandığınız yönteme bir göz atmamız için golf dışında bir versiyonunuz var mı?
Billyoyo

@Billyoyo: Golf edilmeyen kodu ekledi. Ancak fantezi bir şey yok :-)
Master_ex

Biraz golf oynayabilirsiniz. Düzeltme uyarılarına gerek yok, bu yüzden Seti bildirimleri kaldırıldı edebilirsiniz: Set s=new HashSet();. Yönteminde Kodunuz ntek dönüş olabilir: static int n(int x){return x==1?1:x*n(x-1);}. Ve yerini alabilir String zsenin yönteminde oyerine jenerik ile: static<T>void o(T z){System.out.println(z);s.add(z);}. Tüm bunlar 426 bayta düşecek .
Kevin Cruijssen

1

JavaScript (ES6), 186 bayt

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

Not: Çıktı biçiminin ne kadar esnek olduğundan emin değilim, 171 bayt için bunu yapabilirim:

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}

Gerçekleştirerek İşleri Steinhaus-Johnson-Trotter endeksleri karışık dizisinde algoritmasını ve giriş dizisine geri çevirme. Ungolfed:

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 bayt

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

1

Haskell - 135 bayt

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

çıktı:

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

permutationsTakaslara dayanmayan standart işlevi kullanıyorum , bu yüzden permütasyonların permütasyonlarını alıyorum ve takas zinciri olan bir tane buluyorum.

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.