O código mais curto para inverter bit a bit uma string binária

79

Eu acha que aqui não há perguntas fáceis suficientes que os iniciantes possam tentar!

O desafio: Dada uma sequência de entrada aleatória de 1 e 0, como:

10101110101010010100010001010110101001010

Escreva o código mais curto que produz o inverso em bits da seguinte maneira:

01010001010101101011101110101001010110101
ToonAlfrink
fonte

Respostas:

88

J, 5 bytes

Assume que a sequência de entrada está na variável b.

b='0'

Isso não faz o que faria na maioria dos idiomas ...

O operador de comparação J é justo =( =:e =.é atribuição global e local, respectivamente). No entanto, =não funciona como o ==operador normal : ele compara item por item. Tenha em mente que uma matriz é formada assim: 0 2 3 2 3 1 2 3 4. 2 = 0 2 3 2 3 1 2 3 40 1 0 1 0 0 1 0 0por exemplo. Isso é semelhante para uma string: 'a'='abcadcadda'não apenas retorna 0, mas retorna 1 0 0 1 0 0 1 0 0 1(Isso pode ser extrapolado para significar 0com */, o que basicamente significa all.) Nesse caso, no entanto, esse comportamento é excelente, pois queremos uma string de uns e zeros, ou verdadeiro e falso. Como os bools de J são 1 e 0, isso resulta em uma matriz de 1's e0(Eles não são cadeias de caracteres e todos os outros caracteres que 1também resultariam 0nessa matriz.) Isso não precisa ser impresso: J imprime automaticamente o resultado de uma expressão. Espero que tenha sido uma explicação adequada; caso contrário, peça algo que ainda não esteja claro nos comentários. Essa resposta também poderia ter sido '0'&=(ou =&'0'), mas achei que b='0'era mais claro.

ɐɔıʇǝɥʇuʎs
fonte
1
Eu tentei J. Não consigo me concentrar nisso. Acho que não encontrei bons documentos. Aqui, tenha um +1 por ser um louco.
seequ
1
E é por isso que eu nunca vou usar J.
Qix
2
@Qix Por mais ilegível que J seja, este realmente faz sentido para mim, e outras linguagens que possuem operadores que usam um vetor LHS e um RHS escalar se comportam de maneira semelhante.
hvd 10/06
1
O que? Não retorna o resultado certo, pois não? O resultado deveria ter sido uma string de texto (sem espaços), mas com meu conhecimento limitado de J, acho que isso retornará uma lista booleana com um formato de exibição 0 1 0 1 0 ...
Adám
4
Isso não é permitido porque você não pode assumir que a entrada está armazenada em uma determinada variável. =&'0'funciona para o mesmo número de bytes.
Esolanging Fruit
43

GolfScript , 5 bytes

{1^}%

Experimente online.

Como funciona

  • O GolfScript lê toda a entrada do STDIN e a coloca na pilha como uma string.

  • {}% passa por todos os caracteres da string e executa o bloco de código para todos eles.

  • 1^ calcula o OR exclusivo do código ASCII de caracteres com 1. “0” corresponde ao código ASCII 48, “1” ao código ASCII 49.

    Desde 48 ^ 1 = 49e 49 ^ 1 = 48, isso transforma zeros em zeros e zeros em zeros.

  • Depois de concluído, o GolfScript imprime a sequência modificada.

Dennis
fonte
6
Espere, golfscript ?
precisa saber é o seguinte
Eu tinha interpretado mal sua pergunta. Corrigido agora.
Dennis
1
@tolos: Eu editei minha resposta.
Dennis
5
@ToonAlfrink Linguagens de golfe como o GolfScript são aceitas em todos os desafios, desde que sejam de “uso geral”, o que significa que não foram projetadas para desafios específicos.
precisa saber é o seguinte
4
@ kitcar2000 Eu acho que ele ficou mais surpreso que uma tal linguagem existia, ao invés de choque de alguém se atrever a usar GolfScript em uma questão de golfe código;)
Chris Cirefice
35

CJam - 4

q1f^

Este xor é todo caractere com 1.
Diferente da outra resposta CJam, não estou assumindo que a entrada já esteja na pilha.

Experimente em http://cjam.aditsu.net/

aditsu
fonte
2
Então é assim que você usa f.
Dennis
@Dennis De fato. Você pode usar o fórum sf fazer perguntas btw :)
aditsu
30

código de máquina x86 no DOS - 14 13 11 bytes

Bem, ficou mais curto de novo! Depois de escrever uma solução para um desafio não relacionado , notei que o mesmo truque poderia ser aplicado mesmo aqui. Aqui vamos nos:

00000000  b4 08 cd 21 35 01 0a 86  c2 eb f7                 |...!5......|
0000000b

Montagem comentada:

    org 100h

section .text

start:
    mov ah,8        ; start with "read character with no echo"
lop:
    ; this loop runs twice per character read; first with ah=8,
    ; so "read character with no echo", then with ah=2, so
    ; "write character"; the switch is performed by the xor below
    int 21h         ; perform syscall
    ; ah is the syscall number; xor with 0x0a changes 8 to 2 and
    ; viceversa (so, switch read <=> write)
    ; al is the read character (when we did read); xor the low
    ; bit to change 0 to 1 and reverse
    xor ax,0x0a01
    mov dl,al       ; put the read (and inverted character) in dl,
                    ; where syscall 2 looks for the character to print
    jmp lop         ; loop

Solução anterior - 13 bytes

Eu acho que não fica muito mais curto que isso.Na verdade, sim! Obrigado a @ninjalj por remover mais um byte.

00000000  b4 08 cd 21 34 01 92 b4  02 cd 21 eb f3           |...!4.....!..|
0000000d

Esta versão possui interatividade avançada ™ - depois de executá-lo na linha de comando, ele cospe os caracteres "invertidos" desde que você escreva os dígitos de entrada (que não são ecoados); para sair, basta pressionar Ctrl-C.

Diferentemente da solução anterior, isso apresenta alguns problemas ao executar no DosBox - como o DosBox não suporta Ctrl-C corretamente , você é obrigado a fechar a janela do DosBox se quiser sair. Em uma VM com DOS 6.0, ele é executado conforme o esperado.

Fonte NASM:

org 100h

section .text

start:
    mov ah,8
    int 21h
    xor al,1
    xchg dx,ax
    mov ah,2
    int 21h
    jmp start

Solução antiga - 27 25 22 bytes

Isso aceitou sua entrada da linha de comando; funciona sem problemas como um arquivo .COM no DosBox.

00000000  bb 01 00 b4 02 8a 97 81  00 80 f2 01 cd 21 43 3a  |.............!C:|
00000010  1e 80 00 7c f0 c3                                 |...|..|

Entrada NASM:

    org 100h

section .text

start:
    mov bx, 1
    mov ah, 2
loop:
    mov dl, byte[bx+81h]
    xor dl, 1
    int 21h
    inc bx
    cmp bl, byte[80h]
    jl loop
exit:
    ret
Matteo Italia
fonte
2
+1 para o código provavelmente muitos não entendem.
Knerd
1
xchg dx,axé 1 byte menor quemov dl,al
ninjalj 11/11
@ninjalj: woa, obrigado! Ele fez ficam mais curtos depois de tudo!
Matteo Italia
26

Bash + coreutils, 8 bytes

tr 01 10

Recebe entrada de STDIN.


Ou

sed, 8 bytes

y/01/10/
Trauma Digital
fonte
2
Recentemente, criei uma biblioteca / alias de golfe definida para o Bash github.com/professorfish/bash-shelf . você pode raspar um caractere com isso:y 01 10
1
Onde o BASH está envolvido aqui? O que é específico do BASH? Cada reservatório pode chamar tr...
yeti
1
@yeti Nem todo shell chama comandos como bash ou zsh. Em algumas conchas que código sozinho é um erro de sintaxe
mniip
5
É provavelmente seguro assumir que "shell" significa "shell compatível com POSIX" aqui ...
FireFly
@professorfish, você retira um caractere, mas adiciona 48 incluindo a função. Como isso é uma vitória?
Steven Penny
20

CJam , 4 bytes

:~:!

Assume que a sequência original já está na pilha. Imprime a sequência modificada.

Experimente online colando o seguinte código :

"10101110101010010100010001010110101001010":~:!

Como funciona

  • :~avalia cada caractere da sequência, ou seja, substitui o caractere 0 pelo número inteiro 0.

  • :!calcula o NOT lógico de cada número inteiro. Isso transforma zeros em zeros e zeros em zeros.

Dennis
fonte
19

Brainfuck ( 70 71)

>,[>,]<[<]>[<+++++++[>-------<-]<+>>[++<]<[>]++++++++[>++++++<-]>.[-]>]

Explicação:

>,[>,]                       Read characters until there are none left.
<[<]                         Return to start
>[<                          Loop as long as there are characters to invert
  +++++++[>-------<-]        Subtract 49 (ASCII value of 1)
  >[++<]                     If not 0, add 2
  +++[<++++>-]<[>>++++<<-]>> Add 48
  .                          Print
  [-]                        Set current cell to 0
>]                           Loop
kitcar2000
fonte
1
++++++++ [<++++++> -] por que não isso para 48? 8 * 6 vs. 4 * 4 * 3
Cruncher
@Cruncher Adicionado.
kitcar2000
Por que demorou mais? é isso por causa da "correção de bugs"?
Cruncher
1
@Cruncher Sim, eu tive que corrigir um bug onde seria a saída apara 11.
kitcar2000
16

PHP - 19 bytes

<?=strtr($s,[1,0]);

Sim, não é realmente original, eu acho!

Blackhole
fonte
11

Pilha de panquecas , 532 bytes

Put this tasty pancake on top!
[]
Put this delicious pancake on top!
[#]
Put this  pancake on top!
How about a hotcake?
If the pancake is tasty, go over to "#".
Eat all of the pancakes!
Put this supercalifragilisticexpialidociouseventhoughtheso pancake on top!
Flip the pancakes on top!
Take from the top pancakes!
Flip the pancakes on top!
Take from the top pancakes!
Put this supercalifragilisticexpialidociouseventhoughthes pancake on top!
Put the top pancakes together!
Show me a pancake!
If the pancake is tasty, go over to "".

Assume que a entrada é finalizada por um caractere nulo. A estratégia é a seguinte:

  • Pegue um caractere de entrada
  • Subtraia o valor ascii 1dele.
  • Subtraia isso de 0(produzindo um 1se tivéssemos 0, ou um 0se tivéssemos 1)
  • Inclua o valor ascii 0nele
  • Imprima o char.
  • Repetir
Justin
fonte
10

C: 29

i(char*s){*s^=*s?i(s+1),1:0;}

Experimente online aqui .

Obrigado por apontar o truque do XOR, Dennis.

millinon
fonte
8
Mais simples e mais curto:i(char*s){while(*s)*s++^=1;}
edc65
1
Obrigado, @ edc65! Não vou usar isso, porém, já que é uma solução iterativa e não recursiva. Eu não gostaria de receber crédito por isso. Vale a pena notar que a sua substituição whilepor um forresultado imóvel de 28 caracteres.
millinon
6
Como preferir. Uma solução recursiva não é solicitada e, na minha opinião, sempre que possível, uma solução iterativa é melhor do que uma solução recursiva. Divirta-se aplicando essa chamada recursiva a uma sequência de 10k.
edc65
1
Como todas as chamadas, exceto a última, são chamadas recursivas finais, aposto que um compilador a converterá em um loop para reutilizar o quadro da pilha.
millinon
1
@millinon Proof!
deed02392
9

Python 2.7 - 34 *

Oh, quanto este primeiro é péssimo. Muito feio, esse aqui é. 63 caracteres.

print''.join([bin(~0)[3:] if x == '0' else bin(~1)[4:] for x in ''])

Este é um pouco melhor, mas ainda não é tão chique. 44 caracteres.

print''.join([str(int(not(int(x)))) for x in ''])

Desde int(x) and 1retorna int(x)se não for 0 e, caso contrário, False. A solução pode ser reduzida ainda mais para 36 caracteres.

print''.join([str(1-int(x)) for x in ''])

Como join()leva um gerador, os suportes podem ser removidos. 32 caracteres.

print''.join(str(1-int(x))for x in'')

E backticks podem ser usados ​​em vez de str()

print''.join(`1-int(x)`for x in'')

Reduzido para 44 de 34 graças aos ponteiros de @TheRare

Encontrar um complemento é difícil em python, pois bin(-int)retorna -0bxxx, portanto, o acima.

Bassem
fonte
2
Você sabe,(int(x) and 1) == int(x)
Veja
@TheRare eu não, obrigado por isso :)
Bassem
1
Para o registro: zero é falso e diferente de zero é verdadeiro. Para qualquer tipo de sequência (lista, sequência ...), a mesma regra se aplica, mas é verificada a partir do comprimento da sequência. Assim '' == Falsee'hi' == True
Veja
1
Parece que você perdeu alguns espaços. Além disso, podem ser usados ​​backticks para substituir repr (). ''.join(`1-int(x)`for x in'')
seequ
1
Fyi, repr(x)para x <maxint é igual astr(x)
consulte
7

Perl, 9 caracteres

'y/10/01/'

O nono caractere é a bandeira 'p'

Uso:

$ echo '10101001' | perl -pe 'y/10/01/'
Zaid
fonte
2
também funciona como um script sed y/10/01/mas um caractere menor porque ele não precisa de quaisquer bandeiras
4
Você não precisa de aspas simples aqui.
Konrad Borowski
7

Javascript ( ES6 ) 36

alert(prompt().replace(/./g,x=>x^1))
nderscore
fonte
Supondo entrada s, s.replace(/./g,x=>x^1)são 22 caracteres.
Oriol
2
Eu realmente gosto de enviar e enviar.
nderscore
@nderscore Salvar 2 caracteres:p=prompt(p().replace(/./g,x=>x^1))
Gaurang Tandon
@GaurangTandon teria que ser (p=prompt)(p().replace(/./g,x=>x^1))e tem o mesmo comprimento.
N
@ndcorecore Eu também pensei que era assim, mas funcionou sem parênteses também, estranhamente.
Gaurang Tandon
7

Labirinto , 6 bytes

(O labirinto é mais novo que esse desafio, então essa resposta não compete - não que ele esteja vencendo de qualquer maneira ...)

1,
.$@

Este código pressupõe que STDIN contenha apenas os dígitos (em particular, nenhuma nova linha à direita).

O ponteiro de instrução (IP) começa no canto superior esquerdo, indo para a direita. Enquanto houver dígitos para ler, ele percorrerá um loop apertado pelo bloco 2x2 esquerdo: 1pressione 1, ,leia um dígito, faça $XOR com 1 para alternar o último bit, .imprima o resultado. O IP aceita esse loop porque a parte superior da pilha é positiva após o XOR, de modo que ele vire à direita. Quando atingimos EOF, ,retorna -1. Então o XOR renderá -2e com esse valor negativo o IP fará uma curva à esquerda no @e o programa será encerrado.

Esta solução deve ser ótimo para Labyrinth: o que você precisa ,e .para um circuito de I / O e @para terminar o programa. Você precisa de pelo menos dois caracteres (aqui 1e $) para alternar o último bit. E você precisa de pelo menos uma nova linha para um loop que pode ser encerrado.

A menos que ... se ignorarmos o STDERR, ou seja, permitir terminar com um erro, podemos salvar o @e também não precisamos de nenhuma maneira de alternar entre dois caminhos. Nós apenas continuamos lendo e imprimindo até tentarmos acidentalmente imprimir um valor negativo (the -2). Isso permite pelo menos duas soluções de 5 bytes:

1,
.$
,_1$.
Martin Ender
fonte
5

Ruby: 23

p $<.read.tr("01","10")
Josh
fonte
5

Código da máquina de Turing, 32 bytes (1 estado - 3 cores)

Usando a sintaxe da tabela de regras exigida por este simulador de TM online. Emprestado de uma postagem que fiz no meu blog de usuários do Googology Wiki há alguns meses.

0 0 1 r *
0 1 0 r *
0 _ _ * halt

Você também pode testar isso usando esta implementação java.

SuperJedi224
fonte
4

Python 2.x - 44 bytes

print''.join(`1-int(x)`for x in raw_input())

Por que torná-lo complexo ou usar algumas variáveis ​​baratas?

seequ
fonte
Sua possível para salvar alguns caracteres extras, como este: print''.join('1-int(x)'for x in'input()'). Como não consegui obter os backticks no código dos comentários, substituí-los por '.
Willem
Para referência futura, você pode escapar deles com uma barra invertida: `a\`b`-> a`b.
precisa saber é o seguinte
@ willem Isso não funciona para entradas que começam com 0 ou que são maiores que maxint (na base10).
seequ
Obrigado @ nyuszika7h e não pensar sobre aqueles casos TheRare para que a sua solução é boa
Willem
@ Willem Real fácil de esquecer coisas assim. :)
Veja
4

R, 27 caracteres

chartr("01","10",scan(,""))

Uso:

> chartr("01","10",scan(,""))
1: 10101110101010010100010001010110101001010
2: 
Read 1 item
[1] "01010001010101101011101110101001010110101"
plannapus
fonte
3

PHP> 5.4 - 37 caracteres

foreach(str_split($s) as $v)echo 1^$v

$s é a entrada

Try it online

Alireza Fallah
fonte
5
Abuso inteligente da <kbd>tag.
usar o seguinte código
3

TI-BASIC, 7 bytes

Essa é uma função que recebe uma string binária (através Ans) como entrada e retorna a saída como uma string invertida (não revertida), conforme especificado. Para obter mais ajuda, você pode ler o aplicativo da lista not(no wiki do TI-BASIC. Estou usando a versão compilada porque é menor:

»*r>Õ¸r

Em hexadecimal:

BB 2A 72 3E D5 B8 72

Explicação

»*r - Pegue a entrada da função como string e converta para a lista

> - Lista de tubulação fornecida para os próximos operadores

Õ¸r - Retorna o inverso da lista

Timtech
fonte
Quais são todos os espaços no final de »*r>Õ¸r ?
precisa saber é o seguinte
@ kitcar2000 Opa, eu costumava ter o HEX depois disso. Mas depois que a mudei, esqueci de remover os espaços ... já fiz isso agora.
Timtech
Deve ser útil observar que: 1. Na calculadora, isso é exibido como expr(Ans:Returnnot(Ans; 2. Como a sequência não é separada por vírgulas e não começa com a {, ela será avaliada para um número inteiro como 1000010011, não para uma lista; 3. Returnnão funciona da maneira que você escreveu; 4. Isso fornece a saída como uma lista, não como uma string.
lirtosiast
3

Haskell, 22 bytes

map(\c->"10"!!read[c])

Fiquei surpreso com a falta de soluções Haskell para esse desafio, então aqui está uma. Ele avalia como uma função que pega uma string e retorna sua inversa.

Explicação

Nada extravagante aqui.

map(\c->             )  -- For each character c in the input string:
                  [c]   -- wrap c into a string,
              read      -- convert to integer,
        "10"!!          -- and index the string "10" with it.
Zgarb
fonte
3

Entre 93, 25 bytes

0>~1+:#v_$>:#,_@
 ^   -1<

Supondo que a pilha vazia e o EOF leiam -1.

0 envia um \ 0 como terminador nulo

>~1+:#v_ é um loop de entrada, lê ASCII, adiciona 1, verifica EOF + 1 = 0,

^ -1< else subtrai 1 e deixa o valor ASCII empurrado na pilha.

$>:#,_@ coloca a cópia extra de zero no topo da pilha e imprime a sequência binária de cima para baixo

Se a pilha vazia exibir 0, salve 2 bytes com

>~:1+#v_$>:#,_@
^   -1<

É possível uma versão em torno de 15 bytes usando esse mesmo algoritmo se EOF = 0, mas não tenho essa implementação à mão para testar.

sig_seg_v
fonte
3

Javascript ES6, 26 caracteres

s=>s.replace(/\d/g,x=>x^1)
Qwertiy
fonte
3
Por que / \ d / g not /./g
l4m2
2

Python3, 39

Methinks Python não é a melhor linguagem para isso. :)

for i in input():print(1-int(i),end='')

Se você se preocupa em ter uma nova linha após a saída, aqui está uma alternativa de 43 caracteres:

print(''.join("01"[i<"1"]for i in input()))
DLosc
fonte
Código irá funcionar sem a end=''apenas um ,vai fazer :) - a menos que você se preocupa não havendo espaços
Harry Beadle
@BritishColour, não, isso é Python2. A printfunção do Python3 requer ajustar o endparâmetro para suprimir uma nova linha no final de cada impressão. Além disso, de acordo com a especificação do OP, acho que me importo em não haver espaços. :) Obrigado pelo comentário!
DLosc
Aww, legal, eu não sabia disso! Eu trabalho principalmente em 2.7: /
Harry Beadle 08/08
2

J - 11 caracteres

Os valores booleanos em J são representados como números inteiros 0e 1, é claro, também são índices válidos em matrizes (nesse caso, a matriz de 2 caracteres '01')

'01'{~'0'&=
Dan Bron
fonte
Eu acho que essa resposta é tecnicamente mais correta do que a resposta J superior, que gera uma matriz booleana em vez de uma string.
gar
Na verdade, eu não percebi a solução J de melhor classificação quando postei (não sei como eu a perdi, mas percebi). Para ser justo com essa solução, ele diz explicitamente "isso não faz o que as outras soluções fazem". BTW, outra maneira de expressar essa solução (saída literal) em 11 caracteres é [:, ": @ = & '' 0 ''. ''
Dan Bron
Oi, obrigado por outro código! Eu estarei aprendendo mais J com vocês. Sobre essa afirmação, acho que ele estava se referindo ao sinal de igual, que compara cada item em vez de atribuição.
gar
2

C #, 131 bytes

Um pouco atrasado para a festa, mas aqui está o meu. :)

using System;class R{static void Main(string[]a){foreach(var v in a[0].ToCharArray()){Console.Write(int.Parse(v.ToString())^1);}}}
helencrump
fonte
2

MATLAB, 13 bytes

@(x)[97-x '']

Após executar o procedimento acima, basta chamar a função com sua string de entrada para obter a string invertida. Por exemplo, executando:

ans('10101110101010010100010001010110101001010')

impressões:

01010001010101101011101110101001010110101
Tom Carpenter
fonte
2

BotEngine , 4x8 = 32

Não-competitivo, pois o idioma pós-data da pergunta.

Iv2 0 12
 >e>S SS
    e1e0
   ^< <P

Com destaque:

insira a descrição da imagem aqui

SuperJedi224
fonte