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.


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
}

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.



2

C ++, 42 bytes

#include <algorithm>
std::next_permutation

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


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


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.

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

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!


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


@ 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!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.