Permüratör İnşa Et


9

Bu zorluk için bir listeyi girdi olarak alan ve bu listenin permütasyonunu döndüren bir fonksiyon (fonksiyonunuz tam bir program olabilir) yapacaksınız. İşleviniz aşağıdaki gereksinimlere uymalıdır.

  • Deterministik olmalı.

  • İşlevinizi kendisiyle değişken sayıda oluşturmak, permütasyonlarından herhangi birine bir liste alabilmelidir.

Bu bir kod golf sorusudur, bu nedenle cevaplar bayt cinsinden puanlandırılacak, daha az bayt daha iyi olacaktır.

Diğer kurallar

  • Sen herhangi bir tür listeyi, (sürebilir [Integer], [String], [[Integer]]bunun sürece)

    • Boş olamaz
    • En az 16 olası değere sahip farklı nesneler içerebilir. (Bir Haskell kullanamazsınız [()]ve işlevinizin olduğunu iddia edemezsiniz id)
    • Yinelenen nesneler içerebilir (küme yok)
  • Bir program veya işlev yazabilirsiniz, ancak standart ES'ye uymanız gerekir.


Ama S_nsadece döngüseln<3
Leaky Nun

@LeakyNun, simetrik grubu oluşturan tek bir permütasyon istemiyor: bir next_permutationfonksiyon istiyor .
Peter Taylor

Sadece 0 ve 1'lerin listelerine izin vermek yeterli midir?
xnor

Bu kısıtlamanın amacını anladığımdan emin değilim. Boolean listelerine izin verirseniz, iki farklı öğe üzerinde tekrarlanabilirliklere izin vermemenin anlamı nedir?
Dennis

@Dennis İyi bir noktaya değindin. Boole listelerine izin vermeyeceğim. Veya 16'dan az olası değere sahip türler.
Ad Hoc Garf Hunter

Yanıtlar:


4

CJam (11 bayt)

{_e!_@a#(=}

Tek bir yinelenen öğeyle dört öğeli bir liste için tam döngüyü gösteren çevrimiçi demo .

teşrih

{      e# Define a block
  _e!  e#   Find all permutations of the input. Note that if there are duplicate
       e#   elements in the input then only distinct permutations are produced.
       e#   Note also that the permutations are always generated in lexicographic
       e#   order, so the order is independent of the input.
  _@a# e#   Find the index of the input in the list
  (=   e#   Decrement and get the corresponding element of the list
       e#   Incrementing would also have worked, but indexing by -1 feels less
       e#   wrong than indexing by the length, and makes this more portable to
       e#   GolfScript if it ever adds a "permutations" built-in
}

2

Mathematica + Combinatorica (Yerleşik Paket) 34 Bayt

Paketi yüklemek için 19 bayt ve işlev için 15 bayt.

<<"Combinatorica`";NextPermutation

Kullanımı:

%@{c, b, a}

Yerleşik olmadan, 61 Bayt

Extract[s=Permutations[Sort@#],Mod[s~Position~#+1,Length@s]]&

Combinatorica'nın Mathematica'ya tam olarak dahil edilmesi gerekiyor, ancak NextPermutation işlevinin göz ardı edildiğini düşünüyorum.



2

C ++, 42 bayt

#include <algorithm>
std::next_permutation

Bu tam işlem C ++ 'da yerleşiktir.


2
Neden sonra #include?
Yytsi

2

JavaScript (ES6), 145 139 137 134 108 bayt

@Neil sayesinde okkalı bir 25 bayt kurtardı!

Girişi alfabetik karakterler dizisi olarak alır. Bir sonraki permütasyonu başka bir dizi olarak döndürür.

a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,a.concat(a.splice(x+1).sort()))

Nasıl?

Bu, her yinelemede aşağıdaki 4 adımı işleyen sözlükbilimsel düzende bir nesildir :

  1. En büyük X dizinini bulun, böylece bir [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. Büyük endeks bul Y Büyüktür X öyle ki bir [Y]> Bir [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. Değerini takas bir [X] o ile bir [E]

    a[x] = a[y], a[y] = t
  4. [X + 1] 'den son öğeye ve son öğeye kadar olan sekansı artan sözlükbilim sırasına göre sıralayın

    a.concat(a.splice(x + 1).sort())

Misal:

adımlar

gösteri


Tersine çevirmek yerine sıralayamaz mısın? Ayrıca bence v<a[i+1]&&(t=v,x=i)bir bayt kazandırır ve spliceiki slices yerine daha fazla tasarruf yapabilirsiniz .
Neil

@Neil İyi yakala!
Arnauld

Sanırım map112 bayt için iki s'yi de birleştirebildim :a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,t=a.splice(++x).sort(),a.concat(t))
Neil

İtiraf etmeliyim ki a.concat(a.splice(++x).sort())işe yarayacağını sanmıyordum , aksi takdirde
denerdim

@Neil Teşekkürler! Güncellenmiş. (Asıl ihtiyacımız yok çünkü 4 ile daha kurtardı bayt t için concat () ).
Arnauld

1

Jöle , 6 bayt

Œ¿’œ?Ṣ

Permütasyonlar boyunca azalan sözlükbilimsel sırayla döner.

Çevrimiçi deneyin!

Nasıl çalışır

Œ¿’œ?Ṣ  Main link. Argument: A (array)

Œ¿      Compute the permutation index n of A, i.e., the index of A in the
        lexicographically sorted list of permutations of A.
  ’     Decrement the index by 1, yielding n-1.
     Ṣ  Sort A.
   œ?   Getthe (n-1)-th permutation of sorted A.

1

C, 161 bayt

Gerçek O (n) algoritması.

#define S(x,y){t=x;x=y;y=t;}
P(a,n,i,j,t)int*a;{for(i=n;--i&&a[i-1]>a[i];);for(j=n;i&&a[--j]<=a[i-1];);if(i)S(a[i-1],a[j])for(j=0;j++<n-i>>1;)S(a[i+j-1],a[n-j])}

Örnek kullanım:

int main(int argc, char** argv) {
    int i;
    int a[] = {1, 2, 3, 4};

    for (i = 0; i < 25; ++i) {
        printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
        P(a, 4);
    }

    return 0;
}

1

Python 2 , 154 bayt

x=input()
try:exec'%s=max(k for k in range(%s,len(x))if x[%s-1]<x[k]);'*2%tuple('i1kjii');x[i-1],x[j]=x[j],x[i-1];x[i:]=x[:i-1:-1]
except:x.sort()
print x

Çevrimiçi deneyin!


Bu listeye yerinde izin veren bir işlev olarak daha kısa olduğunu düşünüyorum.
orlp

Bunu denedim, ama execbana bir fonksiyonda her türlü hatayı verdi
Dennis

0

Jöle , 10 bayt

ṢŒ!Q©i⁸‘ị®

Çevrimiçi deneyin!

Sırala> tüm permütasyon> girişi bul> 1 ekle> endeksi "tüm permütasyona


@PeterTaylor Düzelttim.
Leaky Nun

Permütasyonlar için spesifik yerleşikler vardır (yani sadece yapabilirsiniz Œ¿‘œ?Ṣ). Aynı algodan beri çalmak istemiyordum.
Outgolfer Erik

@EriktheOutgolfer yinelenen içeren girişler için biraz dağınık olabilir.
Leaky Nun

Hmm ... Sanırım, daha önce bunun için çalışmış bir versiyonum vardı ama bu şeyi kullanıyorsunuz Q. Hala golf yapabilirsiniz ṢŒ!Qµi³‘ị.
Outgolfer Erik


0

PHP , 117 bayt

Girdi / çıktıyı küçük harflerin dize listesi olarak alır

$a=str_split($s=$argn);rsort($a);if(join($a)!=$s)for($n=$s;($c=count_chars)(++$n)!=$c($s););else$n=strrev($s);echo$n;

Ç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.