Introdução
Um código cinza é uma alternativa à representação binária na qual um número é incrementado alternando apenas um bit, em vez de uma quantidade variável de bits. Aqui estão alguns códigos em cinza, juntamente com seus equivalentes decimais e binários:
decimal | binary | gray
-------------------------
0 | 0 | 0
-------------------------
1 | 1 | 1
-------------------------
2 | 10 | 11
-------------------------
3 | 11 | 10
-------------------------
4 | 100 | 110
-------------------------
5 | 101 | 111
-------------------------
6 | 110 | 101
-------------------------
7 | 111 | 100
-------------------------
8 | 1000 | 1100
-------------------------
9 | 1001 | 1101
-------------------------
10 | 1010 | 1111
-------------------------
11 | 1011 | 1110
-------------------------
12 | 1100 | 1010
-------------------------
13 | 1101 | 1011
-------------------------
14 | 1110 | 1001
-------------------------
15 | 1111 | 1000
Padrão de bit cíclico de um código cinza
Às vezes chamada de "binário refletido", a propriedade de alterar apenas um bit de cada vez é facilmente alcançada com padrões de bits cíclicos para cada coluna a partir do bit menos significativo:
bit 0: 0110011001100110011001100110011001100110011001100110011001100110
bit 1: 0011110000111100001111000011110000111100001111000011110000111100
bit 2: 0000111111110000000011111111000000001111111100000000111111110000
bit 3: 0000000011111111111111110000000000000000111111111111111100000000
bit 4: 0000000000000000111111111111111111111111111111110000000000000000
bit 5: 0000000000000000000000000000000011111111111111111111111111111111
...e assim por diante.
Objetivo
Dada uma sequência de entrada não preenchida de um código cinza, aumente o código cinza alternando um único caractere na sequência ou acrescentando a 1
(ao aumentar para a próxima potência de 2) e, em seguida, imprima o resultado como um código cinza não preenchido.
Ressalvas
- Não se preocupe em pegar
0
uma string vazia ou como entrada. - A entrada mais baixa será
1
e não há limite superior para o comprimento da cadeia, exceto as limitações de memória impostas pelo ambiente. - Por sequência não preenchida, quero dizer que não haverá espaços em branco à esquerda ou à direita (exceto uma nova linha à direita) e nem
0
s na entrada ou saída.
Formatos de E / S
Os seguintes formatos são aceitos para entrada e saída, mas as cadeias são incentivadas em relação a outros formatos:
- "bit" mais significativo primeiro
- array de caracteres não-acolchoado ou seqüência de ASCII
'1'
s e'0'
s - matriz inteira não preenchida de
1
s e0
s - matriz booleana não acolchoada
O que não é permitido:
- "bit" menos significativo primeiro
- número inteiro decimal, binário ou unário
- estrutura de dados de comprimento fixo
- matriz de caracteres ou sequência de índices ASCII não imprimíveis
1
e0
Testes
input -> output
1 -> 11
11 -> 10
111 -> 101
1011 -> 1001
1111 -> 1110
10111 -> 10110
101100 -> 100100
100000 -> 1100000
Mais testes podem ser adicionados por solicitação.
Critério
Isso é código-golfe , e o programa mais curto em bytes vence! Todos os laços serão rompidos favorecendo envios anteriores; lacunas padrão se aplicam. A melhor resposta enviada será aceita em 9 de outubro de 2016 e atualizada sempre que melhores respostas forem fornecidas.
fonte
0011
para 8Respostas:
Geléia ,
108 bytesAgradecimentos a Dennis por salvar 2 bytes.
Entrada e saída são listas de 0s e 1s.
Experimente online!
Explicação
O inverso do código Gray é dado por A006068 . Usando isso, não precisamos gerar um grande número de códigos Gray para procurar a entrada. Uma classificação desta sequência dada no OEIS é a seguinte:
Onde
[]
estão os suportes do piso. Considere o exemplo de44
cuja representação binária é101100
. Dividir por 2 e piso é apenas o deslocamento certo, cortando a parte menos significativa. Então, nós estamos tentando XOR os seguintes númerosObserve que a
n
coluna th contém os primeirosn
bits. Portanto, essa fórmula pode ser calculada trivialmente na entrada binária como a redução cumulativa de XOR sobre a lista (que basicamente aplica XOR a cada prefixo da lista e fornece uma lista dos resultados).Isso nos dá uma maneira simples de inverter o código Gray. Depois, apenas incrementamos o resultado e o convertemos novamente no código Gray. Para o último passo, usamos a seguinte definição:
Felizmente, Jelly parece colocar as entradas automaticamente ao tentar fazer o XOR delas. Enfim, aqui está o código:
fonte
Ḟ$
; operadores bit a bit convertidos para int .JavaScript (ES6), 58 bytes
Alterna diretamente o bit apropriado. Explicação: Conforme mostrado na resposta de MartinEnder ♦, cada bit em um código Grey decodificado é o XOR cumulativo, ou paridade, de si mesmo e os bits à esquerda. Em seguida, precisamos incrementar o número que causa uma ondulação de transporte que alterna todos os 1 bits mais à direita para 0 e, em seguida, o próximo 0 para 1. A recodificação resulta em um código com apenas uma posição de 0 bits alternada. Se a paridade de todos os 1 bits for par, o bit mais à direita será 0 e, portanto, apenas alternamos o último bit. Se a paridade de todos os 1 bits for ímpar, os bits mais à direita serão 1, e precisamos encontrar o último 1 bit. Agora é o último dos bits transportados, portanto, o que precisamos alternar é o próximo da direita.
fonte
?
em/.?(?=10*$)/
realmente necessário? Oh, deixa pra lá. Sim. :-)Perl,
2725 bytesInclui +1 para
-p
Dê uma string de entrada no STDIN, por exemplo
gray.pl
:O Perl não possui inteiros baratos de precisão infinita. Então, alterne diretamente o bit certo, que é o mesmo antes de onde seria o último número ímpar 1.
fonte
\G
realmente facilita as coisas para você!\K
torna as coisas ainda mais fáceis para você.\G
implementação também.Haskell,
118 115108 bytesExperimente em Ideone.
Abordagem ingênua:
g
gera o conjunto de todos os códigos cinzas com comprimenton
(com preenchimento de 0),f
chamag
comlength(input)+1
, remove todos os elementos até que0<inputstring>
seja encontrado e retorna o próximo elemento (truncando um possível início0
).fonte
MATL , 18 bytes
Experimente online! Ou verifique todos os casos de teste .
Explicação
Deixei a ( n ) a sequência de números inteiros correspondente aos códigos de Gray ( OEIS A003188 ). O programa usa a caracterização a ( n ) = n piso XOR ( n / 2), onde XOR é bit a bit.
Essencialmente, o código converte a entrada em um número inteiro a 0 , localiza esse número inteiro na sequência e seleciona o próximo termo. Isso requer a geração de um número suficientemente grande de termos da sequência a ( n ). Acontece que 2 · a 0 é suficientemente grande. Isso decorre do fato de o código Gray a ( n ) nunca ter mais dígitos binários que n .
Vamos dar
'101'
um exemplo como exemplo.fonte
CJam (19 bytes)
Demonstração online . Este é um bloco anônimo (função) de matriz de bits para matriz de bits, que a demonstração executa em um loop.
Ele trabalha com o princípio simples de que, se o número de bits definidos for igual, devemos alternar o bit menos significativo e, caso contrário, devemos alternar o bit para a esquerda do bit menos definido. Na verdade, identificar esse bit é muito mais fácil usando hacks de bits em um número inteiro do que usando a lista de bits.
Dissecação
Trabalhando exclusivamente com a matriz de bits, acho que é necessário revertê-la: trabalhar com a extremidade esquerda
1
é muito mais fácil do que a extremidade direita. O melhor que encontrei até agora é (24 bytes):Abordagem alternativa (19 bytes)
Isso converte do código Gray em índice, incrementa e converte novamente no código Gray.
fonte
JavaScript (ES6), 53 bytes (não concorrente)
Uma função recursiva que constrói todos os códigos em cinza até que a entrada seja encontrada e pára na próxima iteração.
A entrada mais alta possível depende do limite de recursão do navegador (cerca de 13 bits no Firefox e 15 bits no Chrome).
fonte
--harmony
adicionado para bytes de penalidade para ter acesso à otimização da recursão da chamada de cauda, o que parece ser possível aqui.Retina, 25 bytes
Tenho certeza de que deve haver uma maneira melhor de fazer isso ...
fonte
^
?05AB1E , 12 bytes
Usos a codificação CP-1252 .
Experimente online!
Explicação
Exemplo para a entrada 1011 .
fonte
Python 2.7, 68 caracteres
Python 3, 68 caracteres
Essa função converte a sequência binária especificada em um número inteiro e, em seguida, x ou o último bit, se o número de bits configurados na string original for par ou alterna o bit para a esquerda do bit definido à direita, se o número de bits configurados no original string é ímpar. Em seguida, converte o resultado em uma sequência binária e remove o
0b
prefixo booleano.fonte
def f(s):
e (assumindo o Python 2) outro usando emprint
vez dereturn
.int()
gera um número inteiro de 32 bits, embora meu requisito seja que você incremente qualquer cadeia de comprimento. Não tenho a certeza que este qualifica como uma submissão válidalong
em vez deint
pode resolver o problema.C ++, 205 bytes
Descrição: os números pares têm um número par de unidades. Variável
z
conta os; sez
for par (z mod 2 = z%2 = 0
- outro ramo), altere o último bit; sez
for ímpar, chame essa função novamente sem o último caractere e calcule o novo valor, depois acrescente o último caractere.Clique aqui para experimentá-lo nos casos de teste.
fonte
Lote,
199197 bytesLê a entrada de STDIN na variável
s
. Remove os 0s e faz uma verificação de paridade nos 1s e, se houver um número ímpar, retira os 0s mais à direita em um loop, parando quando retira um 1.,s
portanto, contém o prefixo de paridade par er
o restante da sequência.s
é definido como zero se estiver em branco para que seu último dígito possa ser alternado e tudo seja concatenado.fonte
Na verdade,
201913 bytesBaseado na resposta Jelly de Martin Ender com minha própria versão de "redução cumulativa de XOR sobre a entrada". Sugestões de golfe são bem-vindas. Experimente online!
Ungolfing
fonte
J, 38 bytes
Experimente online!
Este é essencialmente o algoritmo de Martin em J.
Observe que
22 b.
é XOR.fonte