Classificação de inserção reversa


19

Objetivo

Gere a lista codificada original, a partir dos movimentos que uma Classificação de inserção faria para classificá-la. A lista original terá todos os números de 0até N-1(inclusive) onde Nestá o tamanho da entrada.

Entrada

Uma lista contendo as movimentações necessárias para classificar a lista. Cada valor representa a quantidade de slots deslocados pelo número original (codificado) para estar na posição correta, lembre-se de que esse processo é da esquerda para a direita.
O valor na posição (indexada 0) ina lista de entrada estará entre 0e iinclusive.
Você não precisa lidar com entradas inválidas; nesse caso, qualquer comportamento é aceitável (falha, loop infinito, etc.).

Resultado

A lista embaralhada

Passo a passo para gerar os movimentos

Scrambled List | Moves to sort
[4,0,2,1,3,5]  | [0, , , , , ] #4 stay in place
[4,0,2,1,3,5]  | [0,1, , , , ] #0 is moved 1 slot to the left
[0,4,2,1,3,5]  | [0,1,1, , , ] #2 is moved 1 slot
[0,2,4,1,3,5]  | [0,1,1,2, , ] #1 is moved 2 slot
[0,1,2,4,3,5]  | [0,1,1,2,1, ] #3 is moved 1 slot
[0,1,2,3,4,5]  | [0,1,1,2,1,0] #5 is in the right place already
[0,1,2,3,4,5]

Portanto, para a entrada que [0,1,1,2,1,0]seu programa precisa produzir [4,0,2,1,3,5].
Lembre-se de que os movimentos não estão na posição na lista classificada (final), mas no segmento classificado (a seção em negrito)

Casos de teste

[0,0,0] -> [0,1,2]
[0,1,0,1] -> [1,0,3,2]
[0,0,0,0,0,5] -> [1,2,3,4,5,0]
[0,1,2,3] -> [3,2,1,0]
[0,1,1,1] -> [3,0,1,2]
[0,1,1,2,1,0] -> [4,0,2,1,3,5]

Ganhando

Isso é , então a resposta mais curta vence.

code-golf  array-manipulation  code-golf  code-golf  animation  code-golf  restricted-source  code-golf  java  code-golf  decision-problem  graph-theory  code-golf  conversion  electrical-engineering  code-golf  ascii-art  code-golf  string  substitution  code-golf  math  code-golf  string  set-theory  code-golf  code-golf  compile-time  code-golf  kolmogorov-complexity  binary  code-golf  sequence  cops-and-robbers  code-golf  subsequence  card-games  code-golf  sequence  primes  code-golf  code-golf  number  graphical-output  music  code-golf  ascii-art  code-golf  string  lambda-calculus  code-golf  string  code-generation  code-golf  unicode  code-golf  math  combinatorics  code-golf  balanced-string  code-golf  sequence  cops-and-robbers  code-golf  sequence  cops-and-robbers  code-challenge  fastest-code  chess  code-golf  math  graphical-output  code-golf  string  hello-world  animation  code-golf  number  arithmetic  code-golf  integer  code-golf  code-golf  combinatorics  code-golf  kolmogorov-complexity  graphical-output  code-golf  string  code-golf  code-golf  game  code-golf  math  combinatorics  code-golf  ascii-art  popularity-contest  random  code-golf  arithmetic  number-theory  integer  code-golf  tips  underload  code-golf  math  sequence  primes  code-golf  math  path-finding  code-golf  ascii-art  primes  code-golf  kolmogorov-complexity  alphabet 

11
O programa também pode incluir o comprimento da lista como entrada?
Mbomb007

@ mbomb007 não.
Rod

Podemos usar as etapas (n-1)? O primeiro é desnecessário, pois é sempre zero.
GB

@GB certeza, desde a saída é certa, você pode usar qualquer algoritmo
Rod

Respostas:


14

Gelatina , 12 bytes

L!_UÆ¡$œ?J’U

Experimente online!

Explicação

Podemos basicamente ver as duas listas (a entrada e a saída) como codificando um número inteiro; a entrada codifica um número inteiro na base fatorial e a saída codifica um número inteiro como uma permutação. Felizmente, o Jelly tem embutidos que já estão muito próximos dessas duas codificações, portanto, basta escrever pequenos pedaços de código para converter em um número inteiro e depois voltar para a outra codificação.

L!_UÆ¡$œ?J’U
   U           Reverse {the input}
    Æ¡         and convert from base factorial to integer;
  _   $        subtract that from
L!             the factorial of the length of {the input};
       œ?      then take the nth permutation of
         J     [1,2,...,l], where l is the length of {the input},
          ’    subtract 1 from every elevent,
           U   and reverse it

No caso do fatorial de base, podemos observar que o primeiro elemento da lista deve ser 0, o segundo pode ser 0 ou 1, o terceiro deve ser 0/1/2 e assim por diante. Portanto, temos que reverter a entrada para obter seus elementos na ordem de escrita normal para conversão de base.

Além disso, para que as ordens relativas da conversão fatorial e da conversão de permutação correspondam à operação usada pela classificação por inserção, precisamos fazer dois ajustes: reverter a sequência das permutações e reverter a ordem da lista de saída. Inverter a lista de saída é bastante fácil, necessitando apenas de umU no final do programa. Para reverter a sequência de permutações, subtraímos o fatorial do comprimento de entrada (isso funciona porque o fatorial base produz um número no intervalo de 0 a (comprimento! -1), enquanto as permutações são numeradas pela geléia de 1 a comprimento! , produzindo um off-by-one implícito que cancela o off-one que você normalmente obtém ao subtrair um índice de permutação de um fatorial).

Jelly , 9 bytes, em colaboração com @JonathanAllan

UÆ¡Nœ?J’U

Esta versão do programa é muito semelhante, mas usa um método diferente de reverter a sequência de permutações; simplesmente negar a entrada com Né suficiente para œ?tratar a ordem ao contrário. Além disso, funciona de forma idêntica ao programa anterior.

Experimente online!


4
O_O Que feitiçaria é essa?
21917 DLosc

Oh, legal - eu sabia que meus átomos Æ¡e œ?trabalhariam para isso (eu já havia começado a tentar usá-los para esse desafio mais cedo - eu estava tão perto, só precisava do L!lá).
Jonathan Allan

Código excelente!
Greg Martin

11
De fato, você pode fazer isso em 9 bytes UÆ¡Nœ?L’Uporque eu implementei œ?(e similares) para agir de forma modular (como se eles estivessem usando listas de geléia). O Njusto indexa com o valor negativo. Nota: Eu mudei Jpara L- isso ocorre porque, dado um número, ele faz um intervalo oculto).
Jonathan Allan

6

Mathematica, 92 bytes

Permute[Range[l=Length@#]-1,(c=Cycles@{#}&)@{}©##&@@c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]&

Função pura, recebendo uma lista de números inteiros não negativos como entrada e retornando uma lista de números inteiros não negativos. O código acima contém a ©, que está incorreto: é um espaço reservado para o símbolo de 3 bytes U + F3DE, que o Mathematica representa por um círculo com um ponto e representa a composição das permutações.

c=Cycles@{#}&define uma função que converte uma lista de números inteiros em um Cyclesobjeto que representa uma permutação; por exemplo, c[{3,4}]são os elementos de troca de transposição 3 e 4 de uma lista. c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]pega a lista de entrada e gera as permutações necessárias para desfazer a classificação de inserção. Em seguida, c@{}©##&@@compõe todas essas permutações juntas, começando pela permutação de identidade c@{}. Por fim, Permute[Range[l=Length@#]-1,...]aplica essa permutação à lista indexada em 0 de comprimento apropriado.


11
O que não embutido ?! Certamente ...
Jonathan Allan

3
@{#}&)@{}©##&@@Parece assustador.
Yytsi

6

Python 2, 79 68 bytes

Agradecimentos a Krazor por salvar 10 bytes

Obrigado a TuukkaX por economizar 1 byte

a=input();b=range(len(a));print[b.pop(j-a[j])for j in b[::-1]][::-1]

Funciona gerando os movimentos em sentido inverso


2
Faça esse 66 ! Como sobre: a=input();b=range(len(a));print[b.pop(j-a[j]) for j in b[::-1]][::-1]. Lista compreensões ftw!
FMaz

11
@Krazor Você tem um espaço que poderia ser removido antes for, por isso verifique que 65 eu acho: D
Yytsi

@Krazor Acontece que a compreensão da lista não funcionou muito bem, mas gostei da ideia de usar b [:: - 1]!
matemática viciado em

De jeito nenhum? Comentei com o celular, talvez tenha digitado algo errado. Qual parte não funciona? Para mim, ele interpretou corretamente e atendeu a todos os casos de teste.
FMaz 18/02/19

@ Krazor Oh, opa, não, você está certo. Fui eu quem digitou errado durante o teste.
math junkie

5

JavaScript (ES6), 69 65 63 bytes

a=>a.reverse(b=[...a.keys()]).map(o=>+b.splice(~o,1)).reverse()

Irritantemente, tanto a entrada quanto a saída estão na ordem errada. Editar: salvou 4 bytes graças a @Arnauld. Economizou 2 bytes graças a @ETHproductions.


Eu ainda estava tentando encontrar uma maneira melhor, mas você foi muito mais rápido. Agradável!
Arnauld

11
Você não precisa i, não é?
Arnauld

@ Arnauld Aparentemente não. Comecei tentando entender a resposta do Python, e acabei de perceber que ele não usa i...
Neil

11
Fácil -2:o=>+b.splice(~o,1)
ETHproductions

3

JavaScript (ES6), 73 71 bytes

Economizou 2 bytes graças a ETHproductions

m=>(a=m.map((_,i)=>j=i)).map(_=>a.splice(j,0,+a.splice(j-m[j--],1)))&&a

Casos de teste


Ótima maneira de obter o comprimento e o alcance ao mesmo tempo. Eu ia sugerir a=m.map(_=>j++,j=0), mas esse é o mesmo comprimento e tenho certeza que você já tentou.
ETHproductions

@ETHproductions Você está certo: eu também tentei. :-) (Pode ser interessante notar que este não é equivalente: isto iria definir ja a.lengthvez de a.length-1e exigiria a.splice(--j,0,a.splice(j-m[j],1)[0]))
Arnauld

Heh, eu pensei nisso também, mas eu não acho que foi pena mencionar porque é o mesmo comprimento
ETHproductions

11
Fácil -2:+a.splice(j-m[j--],1)
ETHproductions

2

Haskell , 85 bytes

f x|n<-length x-1=reverse x#[n,n-1..0]
(n:r)#l=r#(take n l++drop(n+1)l)++[l!!n]
x#l=x

Experimente online! Exemplo de uso: f [0,1,1,2,1,0]rendimentos [4,0,2,1,3,5].

f xchama a função #com a lista xinvertida e uma lista [length x - 1, length x - 2, ... , 0]. (n:r)#lexecuta a classificação de inserção reversa retirando recursivamente o nth elemento l, em que l!!nproduz o nth elemento e take n l++drop(n+1)la lista lcom o nth elemento removido.


Haskell, tão bonito.
FMaz

1

perl, 61 bytes

@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p

A saída termina na matriz @o. Exemplo com matriz de entrada como argumentos de linha de comando:

perl -le'@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p;print@o' 0 1 1 2 1 0
402135

1

Ruby, 49 bytes

->l{(w=l.size).times{l.insert(l.shift+w-=1,w)};l}

Executa a "inserção reversa" no lugar dentro da lista, começando com o maior número.

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.