Zbuduj Permuter


9

Do tego wyzwania stworzysz funkcję (twoja funkcja może być kompletnym programem), która pobiera listę jako dane wejściowe i zwraca permutację tej listy. Twoja funkcja musi spełniać następujące wymagania.

  • To musi być deterministyczne.

  • Skomponowanie funkcji ze sobą wiele razy powinno być w stanie uzyskać listę dowolnych permutacji.

To jest pytanie w golfa kodu, więc odpowiedzi będą oceniane w bajtach, przy czym mniej bajtów będzie lepszych.

Dalsze zasady

  • Można wziąć wszelkiego rodzaju listy, ( [Integer], [String], [[Integer]]) tak długo, jak

    • Może być niepusty
    • Może zawierać odrębne obiekty o co najmniej 16 możliwych wartościach. (Nie możesz użyć Haskell [()]i twierdzić, że twoja funkcja to id)
    • Może zawierać zduplikowane obiekty (bez zestawów)
  • Możesz napisać program lub funkcję, ale musisz przestrzegać standardowego IO.


Ale S_njest cykliczny tylko dlan<3
— Leaky Nun

@LeakyNun, nie prosi o pojedynczą permutację, która generuje grupę symetryczną: prosi o next_permutationfunkcję.
— Peter Taylor

Czy wystarczyłoby permutować tylko listy zer i jedynek?
— xnor

Nie jestem pewien, czy rozumiem sens tego ograniczenia. Jeśli zezwolisz na listy wartości logicznych, po co nie dopuścić do iteracji dowolnych dwóch różnych elementów?
— Dennis

@Dennis Masz rację. Niedozwolę list boolejczyków. Lub typy, które mają mniej niż 16 możliwych wartości.
— Ad Hoc Garf Hunter

Odpowiedzi:


4

CJam (11 bajtów)

{_e!_@a#(=}

Demo online pokazujące pełny cykl dla czteroelementowej listy z jednym zduplikowanym elementem.

Sekcja

{      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 (pakiet wbudowany) 34 bajty

19 bajtów, aby załadować pakiet i 15 dla funkcji.

<<"Combinatorica`";NextPermutation

Stosowanie:

%@{c, b, a}

Bez wbudowanego 61 bajtów

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

Combinatorica ma być w pełni włączona do Mathematiki, ale myślę, że funkcja NextPermutation została przeoczona.



2

C ++, 42 bajty

#include <algorithm>
std::next_permutation

Ta dokładna operacja jest wbudowana w C ++.


2
Po co przestrzeń #include?
— Yytsi

2

JavaScript (ES6), 145 139 137 134 108 bajtów

Zaoszczędź 25 bajtów dzięki @Neil!

Pobiera dane wejściowe jako tablicę znaków alfabetycznych. Zwraca następną permutację jako inną tablicę.

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

W jaki sposób?

Jest to generacja w porządku leksykograficznym, która przetwarza 4 następujące kroki przy każdej iteracji:

  1. Znajdź największy indeks X taki, że a [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. Znajdź największy indeks Y większy niż X taki, że a [Y]> a [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. Zamień wartość [X] na wartość [Y]

    a[x] = a[y], a[y] = t
  4. Posortuj sekwencję od [X + 1] do ostatniego elementu włącznie, w rosnącej kolejności leksykograficznej

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

Przykład:

kroki

Próbny


Nie możesz sortować zamiast cofać? Myślę też, że v<a[i+1]&&(t=v,x=i)oszczędza bajt i możesz być w stanie uzyskać więcej oszczędności, używając splicezamiast dwóch slices.
— Neil

@Neil Good catch!
— Arnauld,

Myślę, że udało mi się również połączyć dwa maps, dla 112 bajtów: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

Muszę przyznać, że nie sądziłem, że a.concat(a.splice(++x).sort())pójdzie do pracy, inaczej spróbowałbym ...
— Neil

@Neil Thanks! Zaktualizowano (Przy zachowaniu 4 dodatkowych bajtów, ponieważ tak naprawdę nie potrzebujemy t do konkat () ).
— Arnauld,

1

Galaretka , 6 bajtów

Œ¿’œ?Ṣ

Przechodzi przez permutacje w malejącym porządku leksykograficznym.

Wypróbuj online!

Jak to działa

Œ¿’œ?Ṣ  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 bajtów

Rzeczywisty algorytm O (n).

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

Przykładowe użycie:

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 bajty

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

Wypróbuj online!


Myślę, że jest to krótsza funkcja, która pozwala na umieszczenie listy w miejscu.
— orlp 15.07.17

Próbowałem tego, ale execdałem mi różnego rodzaju błędy w funkcji
— Dennis

0

Galaretka , 10 bajtów

ṢŒ!Q©i⁸‘ị®

Wypróbuj online!

Sortuj> wszystkie permutacje> znajdź dane wejściowe> dodaj 1> indeks do „wszystkich permutacji


@PeterTaylor Naprawiłem to.
— Leaky Nun

Istnieją specjalne wbudowane permutacje (tzn. Możesz to zrobić Œ¿‘œ?Ṣ). Nie miałem ochoty kraść, skoro cóż, to samo algo.
— Erik the Outgolfer

@EriktheOutgolfer może być nieco niechlujny dla danych wejściowych zawierających duplikaty.
— Leaky Nun

Hmm ... Chyba tak, miałem wersję, która wcześniej działała, ale wydaje się, że używasz tego Q. Nadal możesz grać w golfa ṢŒ!Qµi³‘ị.
— Erik the Outgolfer


0

PHP , 117 bajtów

Pobiera dane wejściowe / wyjściowe jako listę ciągów niższych liter

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

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.