Nova ordem nº 2: virar na minha direção

15

Introdução (pode ser ignorado)

Colocar todos os números positivos em sua ordem regular (1, 2, 3, ...) é um pouco chato, não é? Então, aqui está uma série de desafios em torno de permutações (reorganizações) de todos os números positivos. Este é o segundo desafio desta série. O primeiro desafio pode ser encontrado aqui .

Neste desafio, usamos os códigos Gray para reorganizar os números naturais. Um código Gray ou "código binário refletido" é uma codificação binária de tal maneira que dois valores sucessivos diferem em apenas um bit. Uma aplicação prática dessa codificação é usá-la em codificadores rotativos , daí a minha referência a "Turn My Way" .

Codificador rotativo para dispositivos de medição de ângulo marcados em binário de 3 bits.

Observe que essa codificação deixa algum grau de liberdade. Por exemplo, após o binário 1100, existem quatro códigos possíveis: 1101, 1110, 1000 e 0100. É por isso que definirei a(n) como o menor valor não usado anteriormente que difere apenas um caractere na codificação binária. Esta sequência corresponde a A163252 .

Como esse é um desafio de "sequência pura", a tarefa é gerar a(n) para um dado n como entrada, onde a(n) é A163252 .

Tarefa

Dada uma entrada inteira n , produza a(n) no formato inteiro ( não no formato binário).

a(n) é definido como o número inteiro menos positivo que não ocorre anteriormente na sequência, de modo quea(n1) ea(n) diferem em apenas um bit quando escritos em binário.

Nota: a indexação baseada em 1 é assumida aqui; você pode usar a indexação baseada em 0; portanto, a(0)=1;a(1)=3 , etc. Por favor mencione isso na sua resposta se você optar por usá-lo.

Casos de teste

Input | Output
--------------
1     | 1
5     | 4
20    | 18
50    | 48
123   | 121
1234  | 1333
3000  | 3030
9999  | 9997

Regras

  • Entrada e saída são números inteiros (seu programa deve, pelo menos, suportar entrada e saída no intervalo de 1 a 32767)
  • Entrada inválida (0, valores flutuantes, seqüências de caracteres, valores negativos etc.) pode levar a resultados imprevisíveis, erros ou comportamento (não) definido. No A163252 , a(0) é definido como 0. Para esse desafio, ignoraremos isso.
  • Padrão Aplicam- se as regras de E / S .
  • As brechas padrão são proibidas.
  • Isso é , então as respostas mais curtas em bytes ganham

Nota final

Consulte as seguintes perguntas relacionadas (mas não iguais) a PP&CG:

de qualquer maneira
fonte

Respostas:

1

Stax , 19 17 bytes

êÑ{╚α8è╙mc┼σ▀»É▲ü

Execute e depure

Ele pára de funcionar em algum momento após o domínio especificado devido à iteração do índice de bits codificado. (32767)

Descompactado, não jogado e comentado, é assim.

z0,         push an empty array, literal zero, and the input, in that order
             - the zero represents the last calculated value in the sequence
             - the array contains all the previous ones
D           repeat the rest of the program n times (from input)
  +         append the last calculated value to the array
  17r       [0 .. 16] (these are the bit indices necessary to cover the input range)
  {|2nH|^m  calculate candidate values; previous value with each of these bits toggled 
  n-        remove all values previously calculated
  |m        keep the minimum candidate remaining

Execute este

recursivo
fonte
Você está 1 byte atrás da resposta mais curta 05AB1E. Você planeja otimizar ainda mais isso? Caso contrário, eu vou aceitar a resposta de Kevin ...
agtoever
1
Se tiver a oportunidade, trabalharei hoje, nas próximas 14 horas.
recursivo
Tudo certo. Vou mantê-lo aberto por mais um dia. Boa sorte!
agtoever 24/03/19
@agtoever: Obrigado. Eu terminei agora.
recursivo
Bem feito! Você ganha! Parabéns!
agtoever 27/03/19
4

JavaScript (ES6), 65 bytes

1 indexado.

n=>{for(o=p=[k=1];o[k]|~-(i=p^k)&i?k++:k=o[p=k]=!!n--;);return p}

Experimente online!

Comentado

n => {                  // n = index of requested term
  for(                  // for loop:
    o =                 //   o = storage object for the terms of the sequence
    p =                 //   p = last term found in the sequence
      [k = 1];          //   k = current term
    o[k] |              //   if k was already encountered
    ~-(i = p ^ k) & i ? //   or (p XOR k) has more than 1 bit set:
      k++               //     increment k
    :                   //   else:
      k = o[p = k]      //     set o[k], set p to k
        = !!n--;        //     stop if n is equal to 0 or set k to 1; decrement n
  );                    // end of for()
  return p              // return p
}                       // end
Arnauld
fonte
No TIO, recebo um estouro de pilha para n> ~ 1024. Alguma sugestão sobre como lidar com isso em Abu outro ambiente? Regra: " seu programa deve pelo menos suportar entrada e saída no intervalo de
teorias
1
@agtoever Eu atualizei para uma versão não recursiva.
Arnauld
4

Geléia , 26 20 bytes

ṀBLŻ2*^1ị$ḟ⁸Ṃ;
0Ç⁸¡Ḣ

Experimente online!

Um programa completo que aceita n como argumento único. Funciona para todos os casos de teste. Observe também que, embora não seja obrigatório, ele lida com n = 0.

Explicação

Link auxiliar: encontre o próximo termo e adicione-o

Ṁ              | maximum of list so far
 B             | convert to binary
  L            | number of binary digits
   Ż           | 0..above number
    2*         | 2 to the power of each of the above
      ^        | exclusive or with...
       1ị$     | ... the most recent term in the list so far
          ḟ⁸   | filter out anything used already
            Ṃ  | find the minimum
             ; | prepend to existing list

Link principal

0              | start with zero
 Ç             | call the above link
  ⁸¡           | and repeat n times
    Ḣ          | take the last term added
Nick Kennedy
fonte
3

Java (JDK) , 142 138 124 123 132 130 98 bytes

n->{int s[]=new int[9*n],j,k=0;for(;n-->0;s[k=j]++)for(j=0;s[++j]>0|n.bitCount(j^k)>1;);return k;}

Experimente online!

Daniel Widdis
fonte
1
Receio que as importações precisem ser incluídas na contagem de bytes. No entanto, você pode jogar golfe no import java.util.*;+ Set s=new HashSet();para var s=new java.util.HashSet();. Além disso, o resto pode ser golfed a: Integer i=0,j,k=0;for(;i++<n;s.add(k=j))for(j=0;s.contains(++j)|i.bitCount(j^k)>1;);return k;. Boa resposta, no entanto, então +1 de mim. :)
Kevin Cruijssen 20/03/19
1
Economizou mais 2 bytes usando em Stackvez de HashSet. Muito mais lento, mas funciona!
Daniel Widdis 20/03/19
1
Ah, claro, inteligente. E, por mais lento que seja, se podemos salvar um byte, vale a pena enfrentar os desafios do código-golfe. ; p Uma vez tive uma resposta que passou da complexidadeO(n) para O(nn)salvando um byte, haha ​​xD
Kevin Cruijssen 20/03/19
2
Você ainda pode jogar golfe com 126 bytes no segundo golfe que sugeri no meu primeiro comentário. :)
Kevin Cruijssen 20/03/19
2
98 bytes .
Olivier Grégoire
2

Python 2 , 81 bytes

Indexação baseada em 1

l=[0];p=0
exec"n=0\nwhile(p^n)&(p^n)-1or n in l:n+=1\np=n;l+=p,;"*input()
print p

Experimente online!


Python 2 , 79 bytes

Isso leva muito tempo (o 9999 não foi concluído após a execução local por 7 minutos)

l={0};p=0;n=input()
exec'p=min({p^2**k for k in range(n)}-l);l|={p};'*n
print p

Experimente online!

ovs
fonte
1
A entrada máxima 32767 não é suportada (a profundidade da recursão padrão não depende do sistema).
Erik the Outgolfer 19/03/19
Mesmo o caso de teste 9999 fornecido não é suportado. :)
Daniel Widdis
@EriktheOutgolfer Alterou para uma abordagem iterativa, provavelmente ainda não termina a tempo no TIO, mas é executado localmente.
ovs 20/03/19
@ovs Oh, timeouts sozinhos não importam.
Erik the Outgolfer 20/03/19
Legal! Eu apenas tentei por n = 9999 e foi concluído com êxito após cerca de uma hora. +1. Yay! ;-)
agtoever 29/03/19
1

Carvão vegetal , 65 bytes

≔⁰θFN«⊞υθ≔¹ηW¬‹θ⊗η≦⊗ηW∧›η¹∨¬&θη№υ⁻θη≧÷²ηW№υ⁻|θη&θη≦⊗η≔⁻|θη&θηθ»Iθ

Experimente online! Link é a versão detalhada do código. Explicação:

≔⁰θ

Inicialize o resultado para 0.

FN«

nTempos de loop .

⊞υθ

Salve o resultado anterior para não usá-lo novamente.

≔¹ηW¬‹θ⊗η≦⊗η

Encontre o bit mais alto no resultado anterior.

W∧›η¹∨¬&θη№υ⁻θη≧÷²η

Enquanto esse bit for maior que 1, se o bit estiver definido no resultado anterior, tente subtrair esse bit para ver se o resultado é um resultado invisível. Isso garante que os resultados potenciais sejam tentados em ordem crescente de valor.

W№υ⁻|θη&θη≦⊗η

Agora tente XORing esse bit com o resultado anterior, dobrando o bit até encontrar um resultado invisível. Isso lida com os casos em que um bit precisa ser definido, novamente em ordem crescente de valor, mas também o caso em que o bit menos significativo precisa ser alternado, que o loop anterior não se preocupa em testar (porque é mais experiente em testar isso aqui). Se o loop anterior encontrou um resultado invisível, ele nunca será executado; caso contrário, esse loop testará inutilmente esses resultados.

≔⁻|θη&θηθ

Atualize o resultado, na verdade, XORing the bit with it.

»Iθ

Saída do resultado final no final do loop.

Neil
fonte
1

05AB1E , 21 20 18 bytes

ÎFˆ∞.Δ¯θy^bSO¯yå_*

Bastante ineficiente, portanto, quanto maior a entrada, mais tempo leva para obter o resultado. Funciona para entrada0Também , no entanto.

Experimente online ou verifique o primeirontermos .

Explicação:

Î                # Push 0 and the input
 F               # Loop the input amount of times:
  ˆ              #  Pop the current number and add it to the global_array
  ∞.Δ            #  Inner loop starting at 1 to find the first number which is truthy for:
     ¯θy^        #   XOR the last number of the global_array with the loop-number `y`
         b       #   Convert it to binary
          SO     #   Sum it's binary digits
     ¯yå_        #   Check if the loop-number `y` is NOT in the global_array yet
            *    #   Multiply both (only if this is 1 (truthy), the inner loop will stop)
                 # (after the loops, output the top of the stack implicitly)
Kevin Cruijssen
fonte
1

Haskell , 101 bytes

import Data.Bits
(u!n)0=n
(u!n)m|q<-minimum[x|r<-[0..62],x<-[xor(2^r)n],notElem x u]=(n:u)!q$m-1
[]!0

Experimente online!

Parece uma pena incorrer em uma importação apenas por xor, mas ainda não encontrei uma boa solução alternativa. Também me pergunto se existe uma maneira melhor de expressar o loop.

dfeuer
fonte
0

R , 90 bytes

function(n){A=1
while(sum(A|1)<n)A=c(min((x=bitwXor(A[1],2^(0:30)))[x>0&!x%in%A]),A)
A[1]}

Experimente online!

Giuseppe
fonte