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.