Faça uma permutação sem dois inteiros consecutivos próximos um do outro


18

Desafio

Dado um número inteiro n ≥ 4 , imprima uma permutação dos números inteiros [0, n-1] com a propriedade de que não há dois números inteiros consecutivos (números inteiros com diferença absoluta 1) próximos um do outro.

Exemplos

  • 4 → [1, 3, 0, 2]
  • 5 → [0, 2, 4, 1, 3]
  • 6 → [0, 2, 4, 1, 3, 5]
  • 7 → [0, 2, 4, 1, 5, 3, 6]

Você pode usar a indexação 1 em vez disso (usando números inteiros [1, n] em vez de [0, n-1] ).

Seu código deve ser executado no tempo polinomial em n , para que você não possa tentar todas as permutações e testar cada uma.


Quando você diz "gerar uma permutação", você quer dizer uma lista? Ou podemos produzir uma função que implemente o próprio mapeamento de permutação?
— Xnor

@xnor Deve ser produzido de alguma forma legível por humanos. Eu não ligo exatamente como.
— Anush

Seria [[1,3],[0,2]]um formato de saída aceitável?
— Salsicha

@ Shaggy Não é ótimo. Isso significa 1,3,0,2?
— Anush

Respostas:


31

Geléia , 3 2 bytes

ḂÞ

Classifica os números inteiros em [1, ..., n] por seus LSB.

Experimente online!


Uau! Isso é incrível.
— Anush

2
“Classificar por LSB” significa que todos os outros se mudam para o início, mas a definição de Jelly exige que os números em cada metade permaneçam em sua ordem original? Caso contrário, 100 (4) pode estar próximo a 101 (5) e ainda ser "classificado por LSB". Não está com defeito no seu código, mas talvez o comentário descritivo não esteja completo?
— WGroleau

1
@WGroleau Sim, Þclassificação estável, porque é implementada usando a sortedfunção Python , que é garantida como estável .
— User202729

3
O algoritmo é mais impressionante para mim do que o tamanho pequeno, em sua esperteza. Suponho que você também poderia inverter a ordem dos bits, classificar e inverter novamente.
— WGroleau

4
Só pode haver 65536 programas diferentes de dois bytes de geléia. É incrível que muitos deles sejam respostas aos desafios do ppcg.
— Anush 15/05/19




6

Haskell, 22 bytes

f é uma função de n que retorna uma lista ordenada adequadamente. Estou usando a opção de indexação 1.

f n=[2,4..n]++[1,3..n]

6

Oitava , 17 bytes

@(x)[2:2:x,1:2:x]

Experimente online!

Isso usa a mesma abordagem que muitas outras. Concatene dois vetores, um com todo o número par no intervalo inclusivo 2 ... x e todos os números ímpares no intervalo inclusivo 1 ... x . A sintaxe deve ser bastante óbvia, então não vou explicar isso.


1
Não estão 3e 2um ao lado do outro f(4)?
— Pajonk

Opa ... consertado. Contagem de mesmos bytes. :-)
— Stewie Griffin

5

JavaScript (ES6), 40 bytes

f=
n=>[...Array(i=n)].map(_=>(i+--i)%(n|1))
<input type=number min=4 oninput=o.textContent=f(+this.value).join`\n`><pre id=o>

Editar: salvou 1 byte graças a @Arnauld.


5

Gaia , 2 bytes

r∫

Experimente online!

Este simplesmente (estável) ∫ ORTS os inteiros no intervalo [1, entrada] por sua pa r dade.


O mesmo comentário de Jelly: o algoritmo ou a definição da linguagem garante que as duas metades permaneçam na sua ordem original?
— WGroleau

@WGroleau Sim, em Gaia, o meta-operador de classificação é estável.
— Sr. Xcoder

5

R , 39 36 35 bytes

function(x)c(seq(2,x,2),seq(1,x,2))

Experimente online!


Existe um NA à direita para números ímpares.
— JayCe


Culpa da esposa. Tivemos que ir no nosso passeio de bicicleta antes que eu pudesse consertar isso. Mas você raspou alguns bytes também.
— ngm

Sim, eu me senti mal pedindo para você adicionar bytes, então tive que encontrar uma maneira de remover alguns ... funcionou bem.
— JayCe



4

Japonês, 4 bytes

Você também pode substituir uporv para obter um pedido diferente.

õ ñu

Tente

Ou, se pudermos produzir uma matriz de 2 matrizes:

õ ó

Tente


Tecnicamente, o segundo gera uma lista de números separados por vírgulas ;-) Ambos falham 4, infelizmente; você pode corrigir o primeiro alterando upara vou opara õ.
— ETHproductions

3

Mathematica, 50 -> 47 -> 42 bytes

p = Join[Range[2, #, 2], Range[1, #, 2]] &

Experimente online!

Agradecemos a user202729 por apontar o potencial de otimização duplo Join [] instalado do Flatten [] e usar funções puras.

Eu gostaria de acrescentar duas observações.

1) É bastante simples construir uma permutação específica sem sucessão decrescente ou crescente para n> = 4, conforme solicitado no PO.

Consiste em duas listas consecutivas.

Para n
iguais, são: list1 = (2,4, ..., n / 2)
list2 = (1,3, ..., n / 2-1)

Para o número ímpar n, temos:
list1 = (2,4, ..., andar [n / 2])
list2 = (1,3, ..., andar [n / 2])

Para esse "algoritmo", apenas uma decisão deve ser tomada (n par ou ímpar), o resto é apenas escrever n números.

Uma possível solução Mathematica é fornecida na parte superior.

2) Uma questão relacionada é quantas dessas permutas existem em função de n.

Mathematica, 124 bytes

a[0] = a[1] = 1; a[2] = a[3] = 0;
a[n_] := a[n] = (n + 1)*a[n - 1] - (n - 2)*a[n - 2] - (n - 5)*a[n - 3] + (n - 3)*a[n - 4]

Experimente online!

Exemplo:

a[#] & /@ Range[4, 12]

{2, 14, 90, 646, 5242, 47622, ​​479306, 5296790, 63779034}

Contar o número de tais permutações é um problema padrão.

Para n = 4, existem 2: {{2,4,1,3}, {3,1,4,2}}

Para n = 5, existem 14: {{1,3,5,2,4}, {1,4,2,5,3}, {2,4,1,3,5}, {2,4, 1,5,3}, {2,5,3,1,4}, {3,1,4,2,5}, {3,1,5,2,4}, {3,5,1, 4,2}, {3,5,2,4,1}, {4,1,3,5,2}, {4,2,5,1,3}, {4,2,5,3, 1}, {5,2,4,1,3}, {5,3,1,4,2}}

O número a (n) dessas permutações aumenta rapidamente: 2, 14, 90, 646, 5242, 47622, ​​479306, 5296790, 63779034, ...

Para n grande, a razão a (n) / n! parece se aproximar do limite 1 / e ^ 2 = 0,135335 ... Não tenho prova estrita, mas é apenas uma conjectura da evidência numérica. Você pode testar isso tentando executar o programa online.

O programa acima (com base na referência fornecida abaixo) calcula esses números.

Você pode encontrar mais informações na sequência relevante em OEIS: A002464 . O problema de Hertzsprung: maneiras de organizar n reis não atacantes em um tabuleiro n X n, com 1 em cada linha e coluna. Também número de permutações de comprimento n sem sucessões crescentes ou decrescentes.


@ Stewie Griffin Como sou novo aqui, explique com mais detalhes o que você quer dizer. Na minha primeira observação, forneci um algoritmo e um código que resolve o problema no tempo polinomial. Por isso, deve ser considerado uma solução para o desafio. A segunda parte estende o problema interessante. Por isso, deve ser considerado como um comentário.
— Dr. Wolfgang Hintze

Tomei a liberdade de modificar levemente sua submissão para que seu código Mathematica esteja no topo. Com os desafios do código-golfe, é obrigatório fornecer o código real (o menor possível). A forma como eu a formatei, torna-se uma resposta do Mathematica, como você provavelmente pretendia, e ainda tem sua explicação original abaixo. Se você sentir que algo está faltando ou se eu editei incorretamente sua resposta inicial, sinta-se à vontade para editá-la novamente. Bem-vindo ao PPCG! :)
— Kevin Cruijssen

@ Kevin Cruijssen Muito obrigado pela calorosa recepção e pela edição da minha ingênua submissão. Agora adicionei um programa Mathematica para a segunda observação. O que provavelmente não é lege artis. Acima de tudo, não sei como criar o belo link "experimente online".
— Dr. Wolfgang Hintze

Qualquer link pode ser criado usando [some text](the_link). Quanto ao link "Experimente online", em particular, o site https://tio.run/ que está sendo hospedado por nosso próprio @Dennis contém links para todos os tipos de linguagens de programação. A Wolfram Language (Mathematica) é uma delas. Na parte superior, você pode clicar no botão de reprodução para executar o código ou no botão de hiperlink para copiar "Experimente online". links (marcação). E você pode dividir seu código em "Código" (seu envio) real, com um cabeçalho / rodapé opcional para (bonita) impressão de um ou vários casos de teste.
— Kevin Cruijssen 15/05/19

Desculpas pelo meu comentário um tanto franco e falta de resposta depois disso! A resposta apareceu na fila de revisão e não notei o código por causa da formatação. Não é incomum que novos usuários publiquem "observações interessantes" para os desafios, sem fornecer uma resposta real. Embora seja feito de boa fé, não é para isso que o site é. Eu pensei que isso fosse uma resposta. Eu deveria ter respondido ao seu comentário, mas estava com pressa e não consegui escrever um novo comentário; por isso, acabei de remover o antigo. Desculpas! E bem-vindo ao site! Espero que você fique por aqui! :)
— Stewie Griffin



2

Espaço em branco , 161 bytes

Aqui está o envio oficial e não comentado: Experimente online!

push_0   
read_n	
		push_0   
retreive_n			push_1  		
subtract	   dup_and_out[ 
 	
 	]label_s'
   
'push_2  		 
subtract	   dup[ 
 ]jump_next_if_neg:
		  
:dup_and_out[ 
 	
 	]else_jump_back:
 
 
:label_ss'
    
'push_0   
retreive_n			push_2  		 
subtract	   dup_and_out[ 
 	
 	]dup[ 
 ]jump_next:
 
    
:label_ssss'
      
'push_2  		 
subtract	   dup[ 
 ]jump_end_if_neg:
		   
:dup_and_out[ 
 	
 	]else_jump_back:
 
    
:label_sss'
     
'end



Experimente online!

Eu sacrifiquei alguns bytes para que o programa fosse executado sem erros, acredito que poderia perder cerca de 7-8 bytes, e ele ainda seria exibido corretamente, mas também enviaria mensagens de erro, e ninguém quer isso.

Explicação completa de bytes:

[Space][Space][Space][N]                   Push a 0 on the stack
[Tab][Tab][N][Tab][Tab][Tab][Tab]          Read input value and store in heap
[Space][Space][Space][N]                   Push a 0 on the stack again
[Tab][Tab][Tab]                            Retrieve the value from the heap
[Space][Space][Tab][Tab][N]                Push a -1 on the stack
[Tab][Space][Space][Space]                 Add -1 to value
[Space][N][Space]                          Duplicate 
[Tab][N][Space][Tab]                       Output
[N][Space][Space][Space][N]                Set First Label
[Space][Space][Tab][Tab][Space][N]         Push a -2 on the stack
[Tab][Space][Space][Space]                 Subtract 2 from value
[Space][N][Space]                          Duplicate
[N][Tab][Tab][Space][Space][N]             If negative, jump to second label
[Space][N][Space]                          Duplicate
[Tab][N][Space][Tab]                       Output
[N][Space][N][Space][N]                    Jump back to first label
[N][Space][Space][Space][Space][N]         Set Second Label
[Space][Space][Space][N]                   Push a 0 on the stack
[Tab][Tab][Tab]                            Retrieve input value from heap again
[Space][Space][Tab][Tab][Space][N]         Push a -2 on the stack
[Tab][Space][Space][Space]                 This time, Add a -2 to the value
[Space][N][Space]                          Duplicate
[Tab][N][Space][Tab]                       Output
[Space][N][Space]                          Duplicate
[N][Space][N][Space][Tab][N]               Jump to third label
[N][Space][Space][Space][Tab][N]           Set third label
[Space][Space][Tab][Tab][Space][N]         Push a -2 on the stack
[Tab][Space][Space][Space]                 Subtract 2 from value
[Space][N][Space]                          Duplicate
[N][Tab][Tab][Space][Space][Space][N]      Jump to end if negative
[Space][N][Space]                          Duplicate
[Tab][N][Space][Tab]                       Output
[N][Space][N][Space][Tab][N]               Jump back to third label
[N][Space][Space][Space][Space][Space][N]  Set fourth label/end
[N][N][N]                                  Terminate

Algumas coisas para o golfe: push_0, read_STDIN_as_int, push_0, retrievepode ser push_0, duplicate_0, read_STDIN_as_int, retrievepara salvar um byte. E o primeiro rótulo pode ser vazio com em NSSNvez de NSSSN(e o segundo rótulo pode ser NSSSN; terceiro NSSTN; e quarto NSSSSN). Isso deve economizar 8 bytes também. Além disso, você pode remover o primeiro Jump_to_third_labelporque já tem o Set_third_labeldireito abaixo. No total: 140 bytes ; (ou com comentários: experimente online .) -3 bytes se você remover a NNNsaída.
— Kevin Cruijssen 15/05/19


1

Gol> <> , 14 bytes

FL:2%Z}:3=?$|B

Experimente online!

Exemplo de programa completo e como funciona

1AGIE;GDlR~
FL:2%Z}:3=?$|B

1AG          Register row 1 as function G
   IE;       Take number input; halt on EOF
      GD     Call G and print the stack
        lR~  Empty the stack
             Repeat indefinitely

F           |   Repeat n times...
 L              Push loop counter (0..n-1)
  :2%Z}         If even, move to bottom of the stack
       :3=?$    If top == 3, swap top two
                  This is activated only once to make [2 0 3 1]
             B  Return

1

J , 10 bytes

i./:2|1+i.

Experimente online!

Explicação:

  /:          sort
i.            the numbers in the range 0..n-1 
    2|        according the remainder mod 2 of 
      1+i.    the numbers in the range 1..n   

1

Java 8, 56 bytes

n->{for(int i=n;i>0;)System.out.println((i+--i)%(n|1));}

Porta da resposta JavaScript (ES6) do @Neil .

Experimente online.


Resposta antiga de 66 bytes:

n->{String[]r={"",""};for(;n-->0;)r[n%2]+=n+" ";return r[0]+r[1];}

Experimente online.

Explicação:

n->{                  // Method with integer parameter and String return-type
  String[]r={"",""};  //  Result-Strings, both starting empty
  for(;n-->0;)        //  Loop in the range (n, 0]
    r[i%2]+=i+" ";    //   Append `i` and a space to one of the two result-Strings,
                      //   depending on if it is even (first) or odd (second)
  return r[0]+r[1];}  //  Return the two result-Strings appended to each other

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.