Costruisci un Permuter


9

Per questa sfida hai intenzione di creare una funzione (la tua funzione potrebbe essere un programma completo) che accetta un elenco come input e restituisce una permutazione di tale elenco. La tua funzione deve rispettare i seguenti requisiti.

  • Deve essere deterministico.

  • Comporre la tua funzione con se stesso un numero variabile di volte dovrebbe essere in grado di ottenere un elenco di una qualsiasi delle sue permutazioni.

Questa è una domanda di code-golf, quindi le risposte verranno classificate in byte, con meno byte migliori.

Ulteriori regole

  • Si può prendere qualsiasi tipo di lista, ( [Integer], [String], [[Integer]]) purché

    • Può essere non vuoto
    • Può contenere oggetti distinti con almeno 16 possibili valori. (Non puoi usare un Haskell [()]e rivendicare la tua funzione id)
    • Può contenere oggetti duplicati (nessun set)
  • È possibile scrivere un programma o una funzione, ma è necessario rispettare l'IO standard.


Ma S_nè solo ciclico pern<3
— Leaky Nun,

@LeakyNun, non richiede una singola permutazione che genera il gruppo simmetrico: sta chiedendo una next_permutationfunzione.
— Peter Taylor,

Basterebbe solo permutare elenchi di 0 e 1?
— xnor

Non sono sicuro di aver capito il punto di questa limitazione. Se consenti elenchi di booleani, qual è il punto di non consentire iterabili su due elementi distinti?
— Dennis,

@Dennis Hai ragione. Non autorizzerò elenchi di booleani. O tipi che hanno meno di 16 possibili valori.
— Ad Hoc Garf Hunter,

Risposte:


4

CJam (11 byte)

{_e!_@a#(=}

Demo online che mostra l'intero ciclo per un elenco di quattro elementi con un elemento duplicato.

Dissezione

{      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 (pacchetto integrato) 34 byte

19 byte per caricare il pacchetto e 15 per la funzione.

<<"Combinatorica`";NextPermutation

Uso:

%@{c, b, a}

Senza built-in, 61 byte

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

Si suppone che Combinatorica sia completamente integrata in Mathematica, ma penso che la funzione NextPermutation sia stata trascurata.



2

C ++, 42 byte

#include <algorithm>
std::next_permutation

Questa operazione esatta è integrata in C ++.


2
Perché lo spazio dopo #include?
— Yytsi,

2

JavaScript (ES6), 145 139 137 134 108 byte

Salvataggio di ben 25 byte grazie a @Neil!

Accetta input come una matrice di caratteri alfabetici. Restituisce la permutazione successiva come un altro array.

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

Come?

Questa è una generazione in ordine lessicografico che elabora i 4 passaggi seguenti ad ogni iterazione:

  1. Trova l'indice più grande X in modo tale che una [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. Trova l'indice più grande Y maggiore di X in modo tale che una [Y]> a [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. Scambia il valore di una [X] con quello di una [Y]

    a[x] = a[y], a[y] = t
  4. Ordina la sequenza da una [X + 1] fino all'elemento finale compreso, in ordine lessicografico crescente

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

Esempio:

passaggi

dimostrazione


Non puoi ordinare piuttosto che invertire? Inoltre penso che v<a[i+1]&&(t=v,x=i)risparmi un byte e potresti essere in grado di fare più risparmi usando spliceinvece di due slicesecondi.
— Neil,

@Neil Buona cattura!
— Arnauld,

Penso di essere stato in grado di unire anche le due maps, per 112 byte: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,

Devo ammettere che non pensavo che a.concat(a.splice(++x).sort())avrebbe funzionato altrimenti l'avrei provato ...
— Neil,

@Neil Grazie! Aggiornato. (Con 4 più byte salvato perché non abbiamo davvero bisogno di t per concat () ).
— Arnauld,

1

Gelatina , 6 byte

Œ¿’œ?Ṣ

Scorre le permutazioni in ordine lessicografico decrescente.

Provalo online!

Come funziona

Œ¿’œ?Ṣ  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 byte

Algoritmo O (n) effettivo.

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

Esempio di utilizzo:

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 byte

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

Provalo online!


Penso che questo sia più breve in quanto funzione che consente l'elenco sul posto.
— orlp,

Ci ho provato, ma execmi ha dato tutti i tipi di errori in una funzione
— Dennis il

0

Gelatina , 10 byte

ṢŒ!Q©i⁸‘ị®

Provalo online!

Ordina> tutte le permutazioni> trova input> aggiungi 1> indice in "tutte le permutazioni


@PeterTaylor L'ho risolto.
— Leaky Nun,

Ci sono builtin specifici per le permutazioni (cioè puoi semplicemente farlo Œ¿‘œ?Ṣ). Non mi andava di rubare poiché, beh, lo stesso algo.
— Erik the Outgolfer,

@EriktheOutgolfer potrebbe essere un po 'disordinato per gli input che contengono duplicati.
— Leaky Nun,

Hmm ... Immagino di sì, avevo una versione che funzionava in precedenza ma sembra che tu usi la Qcosa. Puoi ancora giocare a golf ṢŒ!Qµi³‘ị.
— Erik the Outgolfer,


0

PHP , 117 byte

Accetta input / output come elenco di stringhe di lettere inferiori

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

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.