Construir um Permuter

9

Para esse desafio, você criará uma função (sua função pode ser um programa completo) que recebe uma lista como entrada e retorna uma permutação dessa lista. Sua função deve obedecer aos seguintes requisitos.

  • Deve ser determinístico.

  • A composição da sua função consigo um número variável de vezes deve ser capaz de obter uma lista para qualquer uma de suas permutações.

Esta é uma questão de código-golfe, para que as respostas sejam pontuadas em bytes, com menos bytes sendo melhores.

Regras adicionais

  • Você pode tomar qualquer tipo de lista, ( [Integer], [String], [[Integer]]) desde que

    • Pode não estar vazio
    • Pode conter objetos distintos com pelo menos 16 valores possíveis. (Você não pode usar um Haskell [()]e afirmar que sua função é id)
    • Pode conter objetos duplicados (sem conjuntos)
  • Você pode escrever um programa ou uma função, mas deve obedecer a IO padrão.

Caçador Ad Hoc Garf
fonte
Mas S_nsó é cíclica paran<3
Leaky Nun
@LeakyNun, não está pedindo uma única permutação que gere o grupo simétrico: está pedindo uma next_permutationfunção.
Peter Taylor
Seria suficiente apenas permutar listas de zeros e zeros?
Xnor
Não sei se entendi o objetivo dessa restrição. Se você permite listas de booleanos, qual é o sentido de não permitir iteráveis ​​sobre dois itens distintos?
Dennis
@ Dennis Você faz um bom argumento. Não permitirei listas de booleanos. Ou tipos com menos de 16 valores possíveis.
Ad Hoc Garf Hunter

Respostas:

4

CJam (11 bytes)

{_e!_@a#(=}

Demonstração online mostrando o ciclo completo de uma lista de quatro elementos com um elemento duplicado.

Dissecação

{      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
}
Peter Taylor
fonte
2

Mathematica + Combinatorica (pacote embutido) 34 bytes

19 bytes para carregar o pacote e 15 para a função.

<<"Combinatorica`";NextPermutation

Uso:

%@{c, b, a}

Sem o built-in, 61 bytes

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

Combinatorica deveria ser totalmente incorporado ao Mathematica, mas acho que a função NextPermutation foi ignorada.

Kelly Lowder
fonte
2

C ++, 42 bytes

#include <algorithm>
std::next_permutation

Essa operação exata é integrada ao C ++.

orlp
fonte
2
Por que o espaço depois #include?
Yytsi 16/07/19
2

JavaScript (ES6), 145 139 137 134 108 bytes

Economizou 25 bytes graças a @Neil!

Recebe a entrada como uma matriz de caracteres alfabéticos. Retorna a próxima permutação como outra matriz.

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

Como?

Esta é uma geração em ordem lexicográfica que processa as 4 etapas a seguir em cada iteração:

  1. Encontre o maior índice X de modo que um [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. Encontre o maior índice Y maior que X, de modo que [Y]> a [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. Troque o valor de um [X] pelo valor de um [Y]

    a[x] = a[y], a[y] = t
  4. Classifique a sequência de um [X + 1] até e incluindo o elemento final, em ordem lexicográfica crescente

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

Exemplo:

passos

Demo

Arnauld
fonte
Você não pode classificar em vez de reverter? Também acho que v<a[i+1]&&(t=v,x=i)economiza um byte e você poderá economizar mais usando em splicevez de dois slices.
Neil
@ Neil Boa captura!
Arnauld
Eu acho que eu era capaz de fundir os dois maps, bem como, para 112 bytes: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
Eu tenho que admitir que eu não achava que a.concat(a.splice(++x).sort())estava indo para o trabalho, caso contrário eu teria tentado ...
Neil
@ Neil Obrigado! Atualizada. (Com mais 4 bytes salvos porque nós realmente não precisa de t para concat () ).
Arnauld
1

Gelatina , 6 bytes

Œ¿’œ?Ṣ

Percorre as permutações em ordem lexicográfica descendente.

Experimente online!

Como funciona

Œ¿’œ?Ṣ  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.
Dennis
fonte
1

C, 161 bytes

Algoritmo O (n) real.

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

Exemplo de uso:

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;
}
orlp
fonte
1

Python 2 , 154 bytes

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

Experimente online!

Dennis
fonte
Eu acho que isso é mais curto como uma função que permite a lista no local.
orlp
Eu tentei isso, mas execme deu todos os tipos de erros em uma função
Dennis
0

Gelatina , 10 bytes

ṢŒ!Q©i⁸‘ị®

Experimente online!

Classifique> toda permutação> encontre entrada> adicione 1> índice em "toda permutação

Freira Furada
fonte
@ PeterTaylor eu corrigi-lo.
Leaky Nun
Existem construtores específicos para permutações (ou seja, você pode simplesmente fazer Œ¿‘œ?Ṣ). Eu não tinha vontade de roubar, já que, bem, o mesmo algo.
Erik the Outgolfer
@EriktheOutgolfer pode ser um pouco confuso para entradas que contêm duplicatas.
Freira vazando
Hmm ... acho que sim, eu tinha uma versão que funcionava para isso anteriormente, mas você parece usar essa Qcoisa. Você ainda pode jogar golfe ṢŒ!Qµi³‘ị.
Erik the Outgolfer
0

PHP , 117 bytes

Toma entrada / saída como lista de cadeias de letras mais baixas

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

Experimente online!

Jörg Hülsermann
fonte