El código más corto para invertir una cadena binaria en bits

79

¡Creo que no hay suficientes preguntas fáciles aquí que los principiantes puedan intentar!

El desafío: dada una cadena de entrada aleatoria de 1 y 0, como:

10101110101010010100010001010110101001010

Escriba el código más corto que genera el inverso de bits de la siguiente manera:

01010001010101101011101110101001010110101
ToonAlfrink
fuente

Respuestas:

88

J, 5 bytes

Asume que la cadena de entrada está en variable b.

b='0'

Esto no hace lo que haría en la mayoría de los idiomas ...

El operador de comparación J es justo =( =:y =.son asignaciones globales y locales, respectivamente). Sin embargo, =no funciona como el ==operador normal : compara elemento por elemento. Tenga en cuenta que una matriz se forma como esto: 0 2 3 2 3 1 2 3 4. 2 = 0 2 3 2 3 1 2 3 4da 0 1 0 1 0 0 1 0 0por ejemplo. Esto es similar a una cadena: 'a'='abcadcadda'no acaba de regresar 0, devuelve 1 0 0 1 0 0 1 0 0 1(Esto se puede extrapolar a significar 0con */, lo que significa básicamente all). En este caso, sin embargo, este comportamiento es excelente, ya que queremos una cadena de unos y ceros, o lo verdadero y lo falso. Como los bools de J son 1 y 0, esto da como resultado una serie de 1's y0's (No son cadenas, y cualquier otro carácter que 1no sea el resultado también 0en esta matriz). Esto no necesita impresión: J imprime automáticamente el resultado de una expresión. Espero que esta haya sido una explicación adecuada, si no, por favor pida algo que aún no está claro en los comentarios. Esta respuesta también podría haber sido '0'&=(o =&'0'), pero sentí que b='0'era más clara.

ɐɔıʇǝɥʇuʎs
fuente
1
He intentado J. No puedo doblegarme a eso. Supongo que no he encontrado buenos documentos. Aquí, ten un +1 por ser un loco.
seequ
1
Y es por eso que nunca usaré J.
Qix
2
@Qix Por muy ilegible que sea J, este realmente tiene sentido para mí, y otros lenguajes que tienen operadores que toman un vector LHS y un RHS escalar se comportan de manera similar.
hvd
1
¿Qué? No devuelve el resultado correcto, ¿verdad? El resultado debería haber sido una cadena de texto (sin espacios), pero con mi conocimiento limitado de J, creo que esto devolverá una lista booleana con una forma de visualización de 0 1 0 1 0 ...
Adám
44
Esto no está permitido porque no puede asumir que la entrada está almacenada en una determinada variable. =&'0'funciona para la misma cantidad de bytes.
Esolanging Fruit
43

GolfScript , 5 bytes

{1^}%

Pruébalo en línea.

Cómo funciona

  • GolfScript lee toda la entrada de STDIN y la coloca en la pila como una cadena.

  • {}% pasa por todos los caracteres de la cadena y ejecuta el bloque de código para todos ellos.

  • 1^ calcula el OR exclusivo del código ASCII de caracteres con 1. "0" corresponde al código ASCII 48, "1" al código ASCII 49.

    Dado 48 ^ 1 = 49y 49 ^ 1 = 48, esto resulta de 0 a 1 y de 1 a 0 de de.

  • Una vez terminado, GolfScript imprime la cadena modificada.

Dennis
fuente
66
Espera, ¿ golfscript ?
ToonAlfrink
Había malinterpretado tu pregunta. Corregido ahora.
Dennis
1
@tolos: he editado mi respuesta.
Dennis
55
@ToonAlfrink Los lenguajes de golf como GolfScript son aceptados en todos los desafíos, siempre y cuando sean de 'propósito general', lo que significa que no están diseñados para desafíos específicos.
kitcar2000
44
@ kitcar2000 Creo que estaba más sorprendido de que tal lenguaje existiera, en lugar de sorprenderse de que alguien se atreviera a usar GolfScript en una pregunta de código de golf;)
Chris Cirefice
35

CJam - 4

q1f^

Este xor es cada carácter con 1.
A diferencia de la otra respuesta de CJam, no estoy asumiendo que la entrada ya está en la pila.

Pruébalo en http://cjam.aditsu.net/

aditsu
fuente
2
Así es como lo usas f.
Dennis
@Dennis De hecho. Puede usar el foro de
SF
30

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

Bueno, ¡se acortó de nuevo! Después de escribir una solución para un desafío no relacionado , noté que el mismo truco podría aplicarse incluso aquí. Así que, aquí vamos:

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

Asamblea 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

Solución anterior - 13 bytes

Creo que no se acorta mucho más que esto.En realidad, lo hizo! Gracias a @ninjalj por eliminar un byte más.

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

Esta versión presenta interactividad avanzada ™ : después de ejecutarla desde la línea de comandos, escupe los caracteres "invertidos" siempre que escriba los dígitos de entrada (que no tienen eco); para salir, solo haz Ctrl-C.

A diferencia de la solución anterior, esto tiene algunos problemas para ejecutarse en DosBox, ya que DosBox no admite Ctrl-C correctamente , se ve obligado a cerrar la ventana de DosBox si desea salir. En cambio, en una máquina virtual con DOS 6.0, se ejecuta según lo previsto.

Fuente NASM:

org 100h

section .text

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

Vieja solución - 27 25 22 bytes

Esto aceptó su entrada desde la línea de comando; funciona sin problemas como un archivo .COM en 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
fuente
2
+1 para el código probablemente no muchos entiendan.
Knerd
1
xchg dx,axes 1 byte más corto quemov dl,al
ninjalj
@ninjalj: woa, gracias! Se hizo más corto después de todo!
Matteo Italia
26

Bash + coreutils, 8 bytes

tr 01 10

Toma información de STDIN.


O

sed, 8 bytes

y/01/10/
Trauma digital
fuente
2
Recientemente hice un conjunto de biblioteca / alias de golf para Bash github.com/professorfish/bash-shelf . puede afeitarse un personaje con eso:y 01 10
1
¿Dónde está involucrado BASH aquí? ¿Qué es BASH específico? Cada caparazón puede llamar tr...
yeti
1
@yeti No todos los shell llaman a comandos como bash o zsh. En algunos shells, ese código solo es un error de sintaxis
mniip
55
Probablemente sea seguro asumir que "shell" significa "shell compatible con POSIX" aquí ...
FireFly
@professorfish se afeita un carácter, pero luego agrega 48 al incluir la función. ¿Cómo es eso una victoria?
Steven Penny
20

CJam , 4 bytes

:~:!

Asume que la cadena original ya está en la pila. Imprime la cadena modificada.

Pruébelo en línea pegando el siguiente código :

"10101110101010010100010001010110101001010":~:!

Cómo funciona

  • :~evalúa cada carácter de la cadena, es decir, reemplaza el carácter 0 con el entero 0.

  • :!calcula el NOT lógico de cada entero. Esto convierte 0's en 1's y 1's en 0's.

Dennis
fuente
19

Brainfuck ( 70 71)

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

Explicación:

>,[>,]                       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
fuente
1
++++++++ [<++++++> -] ¿por qué no esto para 48? 8 * 6 vs. 4 * 4 * 3
Cruncher
@Cruncher agregado.
kitcar2000
¿Por qué se hizo más largo? ¿Es por la "corrección de errores"?
Cruncher
1
@Cruncher Sí, tuve que arreglar un error por el que lo haría de salida apara 11.
kitcar2000
16

PHP - 19 bytes

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

Sí, no muy original, supongo!

Agujero negro
fuente
11

Pila de panqueques , 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 "".

Se supone que la entrada termina con un carácter nulo. La estrategia es la siguiente:

  • Toma un carácter de entrada
  • Reste el valor ascii de 1.
  • Resta eso de 0(dando un 1si lo tuviéramos 0, o un 0si lo tuviéramos 1)
  • Añadir el valor ASCII de 0a ella
  • Imprime el char.
  • Repetir
Justin
fuente
10

C: 29

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

Pruébelo en línea aquí .

Gracias por señalar el truco XOR, Dennis.

Millinon
fuente
8
Más simple y más corto:i(char*s){while(*s)*s++^=1;}
edc65
1
Gracias, @ edc65! Sin embargo, no voy a usar eso, ya que es una solución iterativa en lugar de recursiva. No me gustaría tomar el crédito por ello. Vale la pena señalar que reemplazarlo whilecon un forresultado fijo de una longitud de 28 caracteres.
millinon
66
Como tu prefieras. No se solicita una solución recursiva y, en mi opinión, cada vez que sea posible, una solución iterativa es mejor que una recursiva. Diviértete aplicando esta llamada recursiva a una cadena de 10k.
edc65
1
Como cada llamada, excepto la última, es una llamada recursiva de cola, apuesto a que un compilador la convertirá en un bucle para reutilizar el marco de la pila.
millinon
1
@millinon Proof!
deed02392
9

Python 2.7 - 34 *

Oh, cuánto apesta este primero. Bastante feo, este es. 63 caracteres

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

Este es un poco mejor, pero aún no es tan elegante. 44 caracteres.

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

Desde int(x) and 1devuelve int(x)si no es 0 y de lo contrario es falso. La solución se puede reducir aún más a 36 caracteres.

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

Como join()lleva un generador, los soportes se pueden quitar. 32 caracteres

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

Y se pueden usar backticks en lugar de str()

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

Reducido a 44 de 34 gracias a los punteros de @TheRare

Encontrar el complemento de uno es difícil en python ya que bin(-int)devuelve -0bxxx, de ahí lo anterior.

Bassem
fuente
2
Ya sabes,(int(x) and 1) == int(x)
seequ
@TheRare no lo hice, gracias por eso :)
Bassem
1
Para el registro: cero es falso y distinto de cero es verdadero. Para cualquier tipo de secuencia (lista, cadena ...) se aplica la misma regla, pero se verifica a partir de la longitud de la secuencia. Así '' == Falsey'hi' == True
seequ
1
Parece que te perdiste algunos espacios. Además, los backticks se pueden usar para reemplazar repr (). ''.join(`1-int(x)`for x in'')
seequ
1
Fyi, repr(x)para x <maxint es igual astr(x)
verqu
7

Perl, 9 caracteres

'y/10/01/'

El noveno personaje es la bandera 'p'

Uso:

$ echo '10101001' | perl -pe 'y/10/01/'
Zaid
fuente
2
También funciona como una secuencia de comandos sed y/10/01/, pero con un carácter más corto, ya que no necesita ningún banderas
44
No necesita comillas simples aquí.
Konrad Borowski
7

Javascript ( ES6 ) 36

alert(prompt().replace(/./g,x=>x^1))
nderscore
fuente
Asumiendo entrada s, s.replace(/./g,x=>x^1)son 22 caracteres.
Oriol
2
Me gusta realmente la salida y la entrada.
nderscore
@nderscore Guardar 2 caracteres:p=prompt(p().replace(/./g,x=>x^1))
Gaurang Tandon
@GaurangTandon tendría que ser (p=prompt)(p().replace(/./g,x=>x^1))y esa es la misma longitud.
nderscore
@nderscore Yo también pensé que era así, pero también funcionó sin el paréntesis, extrañamente.
Gaurang Tandon
7

Laberinto , 6 bytes

(El laberinto es más nuevo que este desafío, por lo que esta respuesta no compite, no es que esté ganando de todos modos ...)

1,
.$@

Este código supone que STDIN contiene solo los dígitos (en particular, sin línea nueva final).

El puntero de instrucciones (IP) comienza en la esquina superior izquierda hacia la derecha. Si bien hay dígitos para leer, se desplazará en un ciclo cerrado a través del bloque izquierdo de 2x2: 1presione un 1, ,lea un dígito, $XOR con 1 para alternar el último bit, .imprima el resultado. La IP toma este bucle porque la parte superior de la pila es positiva después del XOR, de modo que tomará un giro a la derecha. Cuando golpeamos EOF, ,regresa en su -1lugar. Luego, el XOR cederá -2y con este valor negativo, la IP girará a la izquierda @y el programa finalizará.

Esta solución debería ser óptima para Labyrinth: necesita ,y .para un bucle de E / S y @para finalizar el programa. Necesita al menos dos caracteres (aquí 1y $) para alternar el último bit. Y necesita al menos una nueva línea para un bucle que se puede terminar.

A menos que ... si ignoramos STDERR, es decir, permitimos terminar con un error, podemos guardar el @y tampoco necesitamos ninguna forma de cambiar entre dos rutas. Seguimos leyendo e imprimiendo hasta que accidentalmente intentamos imprimir un valor negativo (el -2). Esto permite al menos dos soluciones de 5 bytes:

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

Rubí: 23

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

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

Usando la sintaxis de la tabla de reglas requerida por este simulador de TM en línea. Tomado prestado de una publicación que hice en mi blog de usuarios de Googology Wiki hace unos meses.

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

También puede probar esto usando esta implementación de Java.

SuperJedi224
fuente
4

Python 2.x - 44 bytes

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

¿Por qué hacerlo complejo o usar algunas variables engañosas?

seequ
fuente
Su posible para ahorrar algo de caracteres adicionales como esto: print''.join('1-int(x)'for x in'input()'). No pude obtener los backticks en el código de comentario, así que los sustituí por '.
Willem
@willem Para referencia futura, puede escapar de ellos con una barra invertida: `a\`b`-> a`b.
nyuszika7h
@willem Eso no funciona para la entrada que comienza con 0 o la entrada que es más grande que maxint (en base10).
seequ
Gracias @ nyuszika7h y no pensé en esos casos TheRare, así que tu solución es buena
Willem
@willem Realmente fácil olvidarse de cosas así. :)
seequ
4

R, 27 caracteres

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

Uso:

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

PHP> 5.4 - 37 caracteres

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

$s es la entrada

Try it online

Alireza Fallah
fuente
55
Abuso inteligente de la <kbd>etiqueta.
nyuszika7h
3

TI-BASIC, 7 bytes

Esta es una función que toma una cadena binaria (a través Ans) como entrada y devuelve la salida como una cadena invertida (no invertida), como se especifica. Para obtener más ayuda, puede leer la aplicación de la lista not(en el wiki de TI-BASIC. Estoy usando la versión compilada porque es más pequeña:

»*r>Õ¸r

En hexadecimal:

BB 2A 72 3E D5 B8 72

Explicación

»*r - Tome la entrada de función como cadena y conviértala en lista

> - Tubería de la lista dada a los siguientes operadores

Õ¸r - Devuelve el inverso de la lista

Timtech
fuente
¿Cuáles son todos los espacios al final de »*r>Õ¸r ?
kitcar2000
@ kitcar2000 Vaya, solía tener el HEX después de eso. Pero después de moverlo, olvidé eliminar los espacios ... Lo he hecho ahora.
Timtech
Debería ser útil tener en cuenta que: 1. En la calculadora, esto se muestra como expr(Ans:Returnnot(Ans; 2. Debido a que la cadena no está separada por comas y no comienza con a {, se evaluará a un número entero como 1000010011, no una lista; 3. Returnno funciona como lo escribiste; 4. Esto da salida como una lista, no una cadena.
lirtosiast
3

Haskell, 22 bytes

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

Me sorprendió la falta de soluciones de Haskell para este desafío, así que aquí hay una. Se evalúa como una función que toma una cadena y devuelve su inverso.

Explicación

Nada lujoso aquí.

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
fuente
3

Befunge 93, 25 bytes

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

Suponiendo que la pila vacía y EOF leen -1.

0 empuja a \ 0 como un terminador nulo

>~1+:#v_ es un bucle de entrada, lee ascii, agrega 1, comprueba EOF + 1 = 0,

^ -1< de lo contrario, resta 1 y deja el valor ascii empujado en la pila.

$>:#,_@ suelta la copia adicional de cero en la parte superior de la pila, luego imprime la cadena binaria de arriba a abajo

Si la pila vacía lee 0, guarde 2 bytes con

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

Es posible una versión de alrededor de 15 bytes usando este mismo algoritmo si EOF = 0, pero no tengo una implementación tan práctica para probar.

sig_seg_v
fuente
3

Javascript ES6, 26 caracteres

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

Python3, 39

Methinks Python no es el mejor lenguaje para esto. :)

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

Si le importa tener una nueva línea después de la salida, aquí hay una alternativa de 43 caracteres:

print(''.join("01"[i<"1"]for i in input()))
DLosc
fuente
Código funcionará sin el end=''sólo ,va a hacer :) - a menos que se preocupan por estar allí sin espacios
Harry Beadle
@BritishColour, no, eso es Python2. La printfunción de Python3 requiere ajustar el endparámetro para suprimir una nueva línea al final de cada impresión. Además, según la especificación de OP, creo que me importa que no haya espacios. :) Gracias por el comentario, sin embargo!
DLosc
Aww, genial, ¡no lo sabía! Principalmente trabajo en 2.7: /
Harry Beadle
2

J - 11 caracteres

Los valores booleanos en J se representan como enteros 0y 1, por supuesto, también son índices válidos en matrices (en este caso, la matriz de 2 caracteres '01')

'01'{~'0'&=
Dan Bron
fuente
Creo que esta respuesta es técnicamente más correcta que la respuesta J superior, que genera una matriz booleana en lugar de una cadena.
gar
En realidad, no noté la solución J mejor clasificada cuando publiqué (no sé cómo me la perdí, pero lo hice). Para ser justos con esa solución, dice explícitamente "esto no hace lo que hacen las otras soluciones". Por cierto, otra forma de expresar esta solución (salida literal) en 11 caracteres es [:, ": @ = & '' 0 ''.
Dan Bron
Hola, gracias por otro código! Estaré aprendiendo más J de ustedes. Acerca de esa declaración, creo que se refería al signo igual, que compara cada elemento en lugar de la asignación.
gar
2

C #, 131 bytes

Un poco tarde para la fiesta, pero aquí está el mío. :)

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

MATLAB, 13 bytes

@(x)[97-x '']

Después de ejecutar lo anterior, simplemente llame a la función con su cadena de entrada para obtener la cadena invertida. Por ejemplo ejecutando:

ans('10101110101010010100010001010110101001010')

huellas dactilares:

01010001010101101011101110101001010110101
Tom Carpenter
fuente
2

BotEngine , 4x8 = 32

Sin competencia ya que el lenguaje es posterior a la pregunta.

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

Con resaltado:

ingrese la descripción de la imagen aquí

SuperJedi224
fuente