Il codice più breve per invertire bit per bit una stringa binaria


79

Io penso che qui non ci siano abbastanza domande facili da provare per i principianti!

La sfida: data una stringa di input casuale di 1 e 0 come:

10101110101010010100010001010110101001010

Scrivi il codice più breve che genera l'inverso bit-bit in questo modo:

01010001010101101011101110101001010110101

Risposte:


88

J, 5 byte

Presuppone che la stringa di input sia in variabile b.

b='0'

Questo non fa ciò che farebbe nella maggior parte delle lingue ...

L'operatore di confronto J è giusto =( =:e =.sono rispettivamente incarichi globali e locali). Tuttavia, =non funziona come il normale ==operatore: confronta articolo per articolo. Tenete a mente che una matrice è formata in questo modo: 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 0ad esempio. Questo è simile per una stringa: 'a'='abcadcadda'non si limita a restituire 0, ma restituisce 1 0 0 1 0 0 1 0 0 1(può essere estrapolato per significare 0con */, il che significa sostanzialmente all). In questo caso, tuttavia, questo comportamento è eccellente, poiché vogliamo una stringa di uno e zeri, oppure vero e falso. Poiché i bool di J sono 1 e 0, ciò si traduce in una serie di 1'e'0(Non sono stringhe e ogni altro carattere diverso da quello 1comporterebbe anche 0questo array.) Non è necessario stampare: J stampa automaticamente il risultato di un'espressione. Spero che questa sia stata una spiegazione adeguata, in caso contrario, si prega di chiedere qualcosa che non è ancora chiaro nei commenti. Anche questa risposta avrebbe potuto essere '0'&=(o =&'0'), ma ho sentito che b='0'era più chiara.


1
Ho provato J. Non riesco a pensarci. Immagino di non aver trovato buoni documenti. Ecco un +1 per essere un pazzo.
Seequ,

1
Ed è per questo che non userò mai J.
Qix il

2
@Qix Per quanto illeggibile sia J, questo in realtà ha senso per me, e altre lingue che hanno operatori che prendono un LHS vettoriale e un RHS scalare si comportano in modo simile.
hvd,

1
Che cosa? Non restituisce il risultato giusto, vero? Il risultato avrebbe dovuto essere una stringa di testo (senza spazi), ma con la mia conoscenza limitata di J, penso che questo restituirà un elenco booleano con un modulo di visualizzazione di 0 1 0 1 0 ...
Adám

4
Questo non è consentito perché non si può presumere che l'input sia archiviato in una determinata variabile. =&'0'funziona per lo stesso numero di byte.
Esolanging Fruit,

43

GolfScript , 5 byte

{1^}%

Provalo online.

Come funziona

  • GolfScript legge l'intero input da STDIN e lo posiziona nello stack come una stringa.

  • {}% passa attraverso tutti i caratteri nella stringa ed esegue il blocco di codice per tutti loro.

  • 1^ calcola l'OR esclusivo dei caratteri del codice ASCII con 1. “0” corrisponde al codice ASCII 48, “1” al codice ASCII 49.

    Da 48 ^ 1 = 49e 49 ^ 1 = 48, questo trasforma 0 in 1 e 1 in 0.

  • Al termine, GolfScript stampa la stringa modificata.


6
Aspetta, golfscript ?
ToonAlfrink,

Avevo frainteso la tua domanda. Riparato ora.
Dennis,

1
@tolos: ho modificato la mia risposta.
Dennis,

5
@ToonAlfrink I linguaggi del golf come GolfScript sono accettati in tutte le sfide, purché siano "generici", nel senso che non sono progettati per sfide specifiche.
kitcar2000,

4
@ kitcar2000 Penso che sia stato più sorpreso che esistesse un linguaggio del genere, piuttosto che lo shock di qualcuno che osa usare GolfScript in una domanda di codice golf;)
Chris Cirefice,

35

CJam - 4

q1f^

Questo xor ha tutti i caratteri con 1.
A differenza dell'altra risposta di CJam, non presumo che l'input sia già nello stack.

Provalo su http://cjam.aditsu.net/


2
Quindi è così che usi f.
Dennis,

@Dennis In effetti. Puoi usare il forum sf per porre domande tra l'altro :)
aditsu,

30

codice macchina x86 su DOS - 14 13 11 byte

Bene, è diventato di nuovo più corto! Dopo aver scritto una soluzione per una sfida non correlata , ho notato che lo stesso trucco poteva essere applicato anche qui. Quindi eccoci qui:

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

Assemblaggio commentato:

    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

Soluzione precedente - 13 byte

Penso che non sia molto più breve di questo.In realtà, lo ha fatto! Grazie a @ninjalj per aver rasato un altro byte.

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

Questa versione presenta l'interattività avanzata ™ - dopo averlo eseguito dalla riga di comando, sputa i caratteri "invertiti" fintanto che si scrivono le cifre di input (che non fanno eco); per uscire, basta fare un Ctrl-C.

A differenza della soluzione precedente, questo ha alcuni problemi nell'esecuzione in DosBox - poiché DosBox non supporta correttamente Ctrl-C , sei costretto a chiudere la finestra DosBox se vuoi uscire. In una VM con DOS 6.0, invece, funziona come previsto.

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

Vecchia soluzione - 27 25 22 byte

Questo ha accettato il suo input dalla riga di comando; funziona senza problemi come file .COM in 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                                 |...|..|

Input 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

2
+1 per il codice probabilmente non molti capiscono.
Knerd,

1
xchg dx,axè 1 byte più corto dimov dl,al
ninjalj l'

@ninjalj: woa, grazie! Essa ha ottenere più breve, dopo tutto!
Matteo Italia,

26

Bash + coreutils, 8 byte

tr 01 10

Riceve input da STDIN.


O

sed, 8 byte

y/01/10/

2
Di recente ho creato una libreria / alias di golf per Bash github.com/professorfish/bash-shelf . puoi radere un carattere con quello:y 01 10

1
Dove è coinvolto BASH qui? Cosa è specifico di BASH? Ogni shell può chiamare tr...
yeti

1
@yeti Non tutte le shell chiamano comandi come bash o zsh. In alcune shell quel codice da solo è un errore di sintassi
mniip l'

5
Probabilmente è sicuro supporre che "shell" significhi "shell compatibile con POSIX" qui ...
FireFly

@professorfish ti tagli un carattere, ma poi aggiungi 48 includendo la funzione. Come è una vittoria?
Steven Penny,

20

CJam , 4 byte

:~:!

Presuppone che la stringa originale sia già nello stack. Stampa la stringa modificata.

Provalo online incollando il seguente codice :

"10101110101010010100010001010110101001010":~:!

Come funziona

  • :~valuta ogni carattere della stringa, ovvero sostituisce il carattere 0 con il numero intero 0.

  • :!calcola il NOT logico di ciascun numero intero. Questo trasforma 0 in 1 e 1 in 0.


19

Brainfuck ( 70 71)

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

Spiegazione:

>,[>,]                       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

1
++++++++ [<++++++> -] perché non questo per 48? 8 * 6 vs. 4 * 4 * 3
Cruncher

@Cruncher Aggiunto.
kitcar2000,

Perché è durato di più? è a causa del "bug fixing"?
Cruncher,

1
@Cruncher Sì, ho dovuto correggere un bug in cui sarebbe uscita aper 11.
kitcar2000,

16

PHP - 19 byte

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

Sì, non proprio originale, immagino!


11

Stack di pancake , 532 byte

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 "".

Presuppone che l'input sia terminato da un carattere null. La strategia è la seguente:

  • Prendi un carattere di input
  • Sottrai il valore ASCII di 1da esso.
  • Sottrailo da 0(cedendo un 1se avessimo 0, o un 0se avessimo avuto 1)
  • Aggiungi il valore ASCII di 0esso
  • Stampa il carattere.
  • Ripetere

10

C: 29

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

Provalo online qui .

Grazie per aver segnalato il trucco XOR, Dennis.


8
i(char*s){while(*s)*s++^=1;}
Più

1
Grazie, @ edc65! Non lo userò, però, poiché è una soluzione iterativa piuttosto che ricorsiva. Non vorrei prendermi il merito. Vale la pena notare che la sostituzione di un whilecon forancora risultati di una lunghezza di 28 caratteri.
millinon

6
Come preferisci. Non è richiesta una soluzione ricorsiva e, a mio avviso, ogni volta che è possibile, una soluzione iterativa è migliore di una ricorsiva. Divertiti ad applicare questa chiamata ricorsiva a una stringa da 10k.
edc65,

1
Poiché ogni chiamata, tranne l'ultima, è una chiamata ricorsiva di coda, scommetto che un compilatore lo convertirà in un ciclo per riutilizzare il frame dello stack.
millinon

1
@millinon Proof!
deed02392

9

Python 2.7 - 34 *

Oh quanto fa schifo questo primo. Abbastanza brutto, questo è. 63 caratteri.

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

Questo è un po 'meglio ma non è poi così elegante. 44 caratteri.

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

Poiché int(x) and 1restituisce int(x)se non è 0 e in caso contrario Falso. La soluzione può essere ulteriormente ridotta a 36 caratteri.

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

Poiché join()richiede un generatore, le parentesi possono essere rimosse. 32 caratteri.

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

E i backtick possono essere usati invece di str()

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

Ridotto a 44 da 34 grazie ai puntatori di @TheRare

Trovare il proprio complemento è difficile in Python poiché bin(-int)restituisce -0bxxx quindi quanto sopra.


2
Sai,(int(x) and 1) == int(x)
seequ

@TheRare non l'ho fatto, grazie per questo :)
Bassem

1
Per la cronaca: zero è falso e diverso da zero è vero. Per qualsiasi tipo di sequenza (elenco, stringa ...) si applica la stessa regola, ma è verificata dalla lunghezza della sequenza. Così '' == Falsee'hi' == True
seequ

1
Sembra che tu abbia perso alcuni spazi. Inoltre, i backtick possono essere usati per sostituire repr (). ''.join(`1-int(x)`for x in'')
Seequ,

1
Cordiali saluti, repr(x)per x <maxint è uguale astr(x)
vedi l'

7

Perl, 9 caratteri

'y/10/01/'

Il nono personaggio è la bandiera 'p'

Uso:

$ echo '10101001' | perl -pe 'y/10/01/'

2
funziona anche come uno script sed y/10/01/ma un carattere più breve perché non ha bisogno di flag

4
Non hai bisogno di virgolette singole qui.
Konrad Borowski l'

7

Javascript ( ES6 ) 36

alert(prompt().replace(/./g,x=>x^1))

Supponendo che input s, s.replace(/./g,x=>x^1)siano 22 caratteri.
Oriol,

2
Mi piace davvero output e input.
nderscore,

@nderscore Salva 2 caratteri:p=prompt(p().replace(/./g,x=>x^1))
Gaurang Tandon il

@GaurangTandon dovrebbe essere (p=prompt)(p().replace(/./g,x=>x^1))e questa è la stessa lunghezza.
nderscore,

@nderscore Anche io ho pensato che fosse così, ma ha funzionato anche senza la parentesi, stranamente.
Gaurang Tandon,

7

Labirinto , 6 byte

(Labyrinth è più recente di questa sfida, quindi questa risposta non compete, non che vince comunque ...)

1,
.$@

Questo codice presuppone che STDIN contenga solo le cifre (in particolare, nessuna nuova riga finale).

Il puntatore dell'istruzione (IP) inizia nell'angolo in alto a sinistra andando a destra. Mentre ci sono cifre da leggere, scorrerà a ciclo continuo attraverso il blocco 2x2 a sinistra: 1premi un 1, ,leggi una cifra, $XOR con 1 per alternare l'ultimo bit, .stampa il risultato. L'IP prende questo loop perché la parte superiore dello stack è positiva dopo l'XOR, in modo che prenderà una svolta a destra. Quando colpiamo EOF, ,ritorna -1invece. Quindi l'XOR produrrà -2e con questo valore negativo l'IP prende una svolta a sinistra @e il programma termina.

Questa soluzione dovrebbe essere ottimale per Labyrinth: è necessario ,e .per un loop I / O e @per terminare il programma. Sono necessari almeno due caratteri (qui 1e $) per attivare l'ultimo bit. E hai bisogno di almeno una nuova riga per un loop che può essere terminato.

A meno che ... se ignoriamo STDERR, ovvero consentiamo di terminare con un errore, possiamo salvare il @e inoltre non abbiamo bisogno di alcun modo per passare tra due percorsi. Continuiamo a leggere e stampare fino a quando non proviamo accidentalmente a stampare un valore negativo (il -2). Ciò consente almeno due soluzioni a 5 byte:

1,
.$
,_1$.

5

Rubino: 23 anni

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


4

Python 2.x - 44 byte

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

Perché renderlo complesso o utilizzare alcune variabili economiche?


La sua possibile salvare alcuni caratteri extra come questo: print''.join('1-int(x)'for x in'input()'). Non sono riuscito a ottenere i backtick nel codice dei commenti, quindi li ho sostituiti con '.
Willem,

@willem Per riferimento futuro, puoi sfuggirli con una barra rovesciata: `a\`b`-> a`b.
nyuszika7h,

@willem Che non funziona per input che inizia con 0 o input che è più grande di maxint (in base10).
Seequ,

Grazie @ nyuszika7h e non ho pensato a quei casi TheRare, quindi la tua soluzione è buona
Willem,

@willem Davvero facile dimenticare cose del genere. :)
seequ

4

R, 27 caratteri

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

Uso:

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



3

TI-BASIC, 7 byte

Questa è una funzione che accetta una stringa binaria (attraverso Ans) come input e restituisce l'output come stringa invertita (non invertita), come specificato. Per ulteriori informazioni, è possibile leggere l'applicazione dell'elenco tramite not(il wiki TI-BASIC. Sto usando la versione compilata perché è più piccola:

»*r>Õ¸r

In esadecimale:

BB 2A 72 3E D5 B8 72

Spiegazione

»*r - Prendi l'input della funzione come stringa e converti in elenco

> - Elenco di pipe fornite agli operatori successivi

Õ¸r - Restituisce l'inverso dell'elenco


quali sono tutti gli spazi alla fine di »*r>Õ¸r ?
kitcar2000,

@ kitcar2000 Oops, dopo avevo l'esagono. Ma dopo averlo spostato, ho dimenticato di rimuovere gli spazi ... L'ho fatto ora.
Timtech,

Dovrebbe essere utile notare che: 1. Sulla calcolatrice questo viene visualizzato come expr(Ans:Returnnot(Ans; 2. Poiché la stringa non è separata da virgole e non inizia con a {, verrà valutata in un numero intero come 1000010011, non in un elenco; 3. Returnnon funziona come l'hai scritto; 4. Ciò fornisce un output come un elenco, non una stringa.
lirtosiast

3

Haskell, 22 byte

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

Sono stato sorpreso dalla mancanza di soluzioni Haskell a questa sfida, quindi eccone una. Valuta una funzione che accetta una stringa e restituisce il suo inverso.

Spiegazione

Niente di speciale qui.

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.

3

Befunge 93, 25 byte

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

Supponendo che stack vuoto ed EOF leggano entrambi -1.

0 invia un \ 0 come terminatore null

>~1+:#v_ è un ciclo di input, legge ascii, aggiunge 1, controlla EOF + 1 = 0,

^ -1< else sottrae 1 e lascia il valore ASCII spinto nello stack.

$>:#,_@ rilascia la copia aggiuntiva di zero in cima allo stack, quindi stampa la stringa binaria dall'alto verso il basso

Se lo stack vuoto legge 0, salvare 2 byte con

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

Una versione di circa 15 byte è possibile usando questo stesso algoritmo se EOF = 0, ma non ho una tale implementazione a portata di mano con cui testare.


3

Javascript ES6, 26 caratteri

s=>s.replace(/\d/g,x=>x^1)

3
Perché / \ d / g no /./g
l4m2


2

Python3, 39

Python non è la lingua migliore per questo. :)

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

Se ti interessa avere una nuova riga dopo l'output, ecco un'alternativa di 43 caratteri:

print(''.join("01"[i<"1"]for i in input()))

Il codice funzionerà senza il end=''solo ,testamento :) - a meno che non ti interessi che non ci siano spazi
Harry Beadle

@BritishColour, no, questo è Python2. La printfunzione di Python3 richiede l' ottimizzazione del endparametro per eliminare una nuova riga alla fine di ogni stampa. Inoltre, secondo le specifiche di OP, penso che mi importi che non ci siano spazi. :) Grazie per il commento, però!
DLosc

Oh, bello, non lo sapevo! Lavoro principalmente in 2.7: /
Harry Beadle l'

2

J - 11 caratteri

I valori booleani in J sono rappresentati come numeri interi 0e 1, che ovviamente sono anche indici validi in array (in questo caso, l'array a 2 caratteri '01')

'01'{~'0'&=

Penso che questa risposta sia tecnicamente più corretta della risposta J superiore, che genera un array booleano anziché una stringa.
gar

In realtà non ho notato la soluzione J più votata quando ho pubblicato (non so come l'ho persa, ma l'ho fatto). Per essere onesti con quella soluzione, dice esplicitamente "questo non fa quello che fanno le altre soluzioni". A proposito, un altro modo per esprimere questa soluzione (output letterale) in 11 caratteri è [:, ": @ = & '' 0 ''.
Dan Bron,

Ciao, grazie per un altro codice! Imparerò più J da voi ragazzi. A proposito di tale affermazione, penso che si riferisse al segno di uguale, che confronta ogni elemento anziché l'assegnazione.
gar

2

C #, 131 byte

Un po 'tardi alla festa, ma ecco il mio. :)

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

2

MATLAB, 13 byte

@(x)[97-x '']

Dopo aver eseguito quanto sopra, basta chiamare la funzione con la stringa di input per ottenere la stringa invertita. Ad esempio in esecuzione:

ans('10101110101010010100010001010110101001010')

stampe:

01010001010101101011101110101001010110101

2

BotEngine , 4x8 = 32

Non competitiva poiché la lingua postdatizza la domanda.

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

Con evidenziazione:

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.