Le code le plus court pour inverser au niveau binaire une chaîne binaire

79

Moi pense qu'il n'y a pas assez de questions faciles ici que les débutants peuvent essayer!

Le défi: Avec une chaîne d'entrée aléatoire composée de 1 et de 0 tels que:

10101110101010010100010001010110101001010

Ecrivez le code le plus court qui produit l'inverse en bits, comme suit:

01010001010101101011101110101001010110101
ToonAlfrink
la source

Réponses:

88

J, 5 octets

Suppose que la chaîne d'entrée est dans variable b.

b='0'

Cela ne fait pas ce qu’il ferait dans la plupart des langues ...

L'opérateur de comparaison J est juste =( =:et =.sont des affectations globales et locales, respectivement). Cependant, =cela ne fonctionne pas comme un ==opérateur normal : il compare élément par élément. Gardez à l' esprit qu'un tableau est formé comme suit: 0 2 3 2 3 1 2 3 4. 2 = 0 2 3 2 3 1 2 3 4donne 0 1 0 1 0 0 1 0 0par exemple. Ceci est similaire pour une chaîne: 'a'='abcadcadda'ne retourne pas simplement 0, elle retourne 1 0 0 1 0 0 1 0 0 1(ceci peut être extrapolé à signifier 0avec */, ce qui signifie fondamentalement all.) Dans ce cas cependant, ce comportement est excellent, puisque nous voulons une chaîne de uns et de zéros, ou vrai et faux. Puisque les bools de J sont 1 et 0, cela donne un tableau de 1et0's (ce ne sont pas des chaînes, et tout autre caractère que cela 1aurait également pour résultat 0dans ce tableau.) Cela n'a pas besoin d'être imprimé: J imprime automatiquement le résultat d'une expression. J'espère que c'était une explication adéquate, sinon demandez s'il vous plaît quelque chose qui n'est pas encore clair dans les commentaires. Cette réponse aurait également pu être '0'&=(ou =&'0'), mais j’ai pensé que b='0'c’était plus clair.

ıʇǝɥʇuʎs
la source
1
J'ai essayé J. Je ne peux pas y penser. Je suppose que je n'ai pas trouvé de bons documents. Ici, un +1 pour être un fou.
seequ
1
Et c'est pourquoi je n'utiliserai jamais J.
Qix
2
@ Qix Aussi illisible que J soit, celui-ci me semble tout à fait logique, et d’autres langages ayant des opérateurs prenant un vecteur LHS et un scalaire RHS se comportent de la même manière.
hvd
1
Quelle? Cela ne donne pas le bon résultat, n'est-ce pas? Le résultat aurait dû être une chaîne de texte (sans espaces), mais avec ma connaissance limitée de J, je pense que cela va renvoyer une liste booléenne avec une forme d'affichage de 0 1 0 1 0 ...
Adám
4
Ceci n'est pas autorisé car vous ne pouvez pas supposer que l'entrée est stockée dans une certaine variable. =&'0'fonctionne pour le même nombre d'octets.
Esolanging Fruit
43

GolfScript , 5 octets

{1^}%

Essayez-le en ligne.

Comment ça fonctionne

  • GolfScript lit l'intégralité de l'entrée de STDIN et la place sur la pile en tant que chaîne.

  • {}% parcourt tous les caractères de la chaîne et exécute le bloc de code pour chacun d'eux.

  • 1^ calcule le OU exclusif des caractères du code ASCII avec 1. «0» correspond au code ASCII 48, «1» au code ASCII 49.

    Depuis 48 ^ 1 = 49et 49 ^ 1 = 48, cela transforme les 0 en 1 et les 1 en 0.

  • Une fois terminé, GolfScript imprime la chaîne modifiée.

Dennis
la source
6
Attends, golfscript ?
ToonAlfrink
J'avais mal interprété votre question. Correction maintenant.
Dennis
1
@tolos: j'ai modifié ma réponse.
Dennis
5
@ToonAlfrink Les langages de golf tels que GolfScript sont acceptés dans tous les défis, dans la mesure où ils sont «polyvalents», ce qui signifie qu'ils ne sont pas conçus pour des défis spécifiques.
kitcar2000
4
@ kitcar2000 Je pense qu'il était plus surpris par l'existence d'un tel langage que par le choc de quelqu'un qui ose utiliser GolfScript pour une question sur le code de golf;)
Chris Cirefice
35

CJam - 4

q1f^

Chaque caractère de
ce x est composé de 1. À la différence de l'autre réponse de CJam, je ne suppose pas que l'entrée est déjà sur la pile.

Essayez-le sur http://cjam.aditsu.net/

Aditsu
la source
2
Alors c'est comme ça que vous utilisez f.
Dennis
@ Dennis En effet. Vous pouvez utiliser le forum sf pour poser des questions au fait :)
Aditsu
30

Code machine x86 sous DOS - 14 13 11 octets

Eh bien, il est devenu plus court encore! Après avoir écrit une solution pour un défi sans rapport , j'ai remarqué que le même truc pouvait être appliqué même ici. Alors on y va:

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

Assemblée commentée:

    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

Solution précédente - 13 octets

Je pense que ça ne devient pas beaucoup plus court que ça.En fait, ça l'a fait! Merci à @ninjalj pour avoir supprimé un octet de plus.

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

Cette version propose une interactivité avancée ™ - après son exécution à partir de la ligne de commande, elle crache les caractères "inversés" tant que vous écrivez les chiffres saisis (qui ne sont pas répercutés). pour sortir, faites juste un Ctrl-C.

Contrairement à la solution précédente, cela ne fonctionne pas correctement dans DosBox. DosBox ne prenant pas correctement en charge la combinaison de touches Ctrl-C , vous êtes obligé de fermer la fenêtre DosBox si vous souhaitez quitter. Dans une machine virtuelle avec DOS 6.0, il s'exécute comme prévu.

Source NASM:

org 100h

section .text

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

Ancienne solution - 27 25 22 octets

Cela acceptait sa saisie depuis la ligne de commande; fonctionne correctement en tant que fichier .COM dans 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                                 |...|..|

Entrée 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
la source
2
+1 pour le code probablement pas beaucoup comprendre.
Knerd
1
xchg dx,axest 1 octet plus court quemov dl,al
ninjalj
@ninjalj: woa, merci! Il est devenu plus court après tout!
Matteo Italia
26

Bash + coreutils, 8 octets

tr 01 10

Prend l'entrée de STDIN.


Ou

sed, 8 octets

y/01/10/
Trauma numérique
la source
2
J'ai récemment créé une bibliothèque de golf / un alias pour Bash github.com/professorfish/bash-shelf . vous pouvez raser un caractère avec ça:y 01 10
1
Où est BASH impliqué ici? Qu'est-ce qui est spécifique à BASH? Chaque shell peut appeler tr...
yeti
1
@yeti Tous les shell n'appellent pas des commandes telles que bash ou zsh. Dans certains shells, ce code seul est une erreur de syntaxe
mniip
5
Il est probablement prudent de supposer que "shell" signifie "shell compatible POSIX" ici ...
FireFly
@professorfish vous rasez un caractère, puis ajoutez 48 en incluant la fonction. Comment est-ce une victoire?
Steven Penny
20

CJam , 4 octets

:~:!

Suppose que la chaîne d'origine est déjà sur la pile. Imprime la chaîne modifiée.

Essayez-le en ligne en collant le code suivant :

"10101110101010010100010001010110101001010":~:!

Comment ça fonctionne

  • :~évalue chaque caractère de la chaîne, c'est-à-dire qu'il remplace le caractère 0 par l' entier 0.

  • :!calcule le NON logique de chaque entier. Cela transforme les 0 en 1 et les 1 en 0.

Dennis
la source
19

Brainfuck ( 70 71)

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

Explication:

>,[>,]                       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
la source
1
++++++++ [<++++++> -] pourquoi pas pour 48 personnes? 8 * 6 vs. 4 * 4 * 3
Cruncher
@Cruncher Ajouté.
kitcar2000
Pourquoi est-ce devenu plus long? est-ce à cause de la "correction de bugs"?
Cruncher
1
@Cruncher Oui, je devais corriger un bug où il serait sortie apour 11.
kitcar2000
16

PHP - 19 octets

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

Oui, pas vraiment original, je suppose!

Trou noir
la source
11

Pile de crêpes , 532 octets

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

Cela suppose que l’entrée se termine par un caractère nul. La stratégie est la suivante:

  • Prendre un caractère de saisie
  • Soustrayez la valeur ascii 1de celle-ci.
  • Soustrayez cela de 0(donnant un 1si nous avions 0, ou un 0si nous avions 1)
  • Ajoutez la valeur ascii de 0lui
  • Imprimer le caractère.
  • Répéter
Justin
la source
10

C: 29

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

Essayez-le en ligne ici .

Merci d'avoir signalé l'astuce XOR, Dennis.

Millinon
la source
8
Plus simple et plus court:i(char*s){while(*s)*s++^=1;}
edc65
1
Merci, edc65! Je ne vais pas l'utiliser, cependant, puisqu'il s'agit d'une solution itérative plutôt que récursive. Je ne voudrais pas en prendre le crédit. Il est à noter que le remplacement de votre whileavec un forrésultat fixe d'une longueur de 28 caractères.
Millinon
6
Comme tu préfère. Une solution récursive n'est pas demandée et, à mon avis, chaque fois qu'elle est possible, une solution itérative est préférable à une solution récursive. Amusez-vous à appliquer cet appel récursif à une chaîne de 10k.
Edc65
1
Étant donné que chaque appel, à l'exception du dernier, est un appel récursif, je parie qu'un compilateur le convertira en boucle afin de réutiliser le cadre de la pile.
Millinon
1
@ Millinon Preuve!
deed02392
9

Python 2.7 - 34 *

Oh, combien ce premier est nul. Assez moche, celui-ci est. 63 caractères.

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

Celui-ci est un peu mieux mais toujours pas aussi sophistiqué. 44 caractères.

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

Depuis int(x) and 1renvoie int(x)si ce n'est pas 0 et sinon Faux. La solution peut encore être réduite à 36 caractères.

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

Depuis join()prend un générateur, les supports peuvent être supprimés. 32 caractères.

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

Et les backticks peuvent être utilisés à la place de str()

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

Réduit à 44 contre 34 grâce aux indications de @TheRare

Trouver son complément est difficile en python puisque bin(-int)renvoie -0bxxx d’où ce qui précède.

Bassem
la source
2
Vous savez,(int(x) and 1) == int(x)
seequ
@TheRare je n'ai pas, merci pour cela :)
Bassem
1
Pour mémoire, zéro est faux et non nul est vrai. Pour n'importe quel type de séquence (liste, chaîne ...), la même règle s'applique, mais elle est vérifiée à partir de la longueur de la séquence. Ainsi '' == Falseet'hi' == True
voir le
1
On dirait que vous avez manqué des espaces. De plus, des backticks peuvent être utilisés pour remplacer repr (). ''.join(`1-int(x)`for x in'')
seequ
1
Fyi, repr(x)pour x <maxint est égal àstr(x)
seequ
7

Perl, 9 caractères

'y/10/01/'

Le 9ème caractère est le drapeau 'p'

Usage:

$ echo '10101001' | perl -pe 'y/10/01/'
Zaid
la source
2
fonctionne aussi comme un script sed y/10/01/mais un caractère plus court car il n'a pas besoin de drapeaux
4
Vous n'avez pas besoin de guillemets simples ici.
Konrad Borowski
7

Javascript ( ES6 ) 36

alert(prompt().replace(/./g,x=>x^1))
Nderscore
la source
En supposant que l'entrée soit s, il s.replace(/./g,x=>x^1)y a 22 caractères.
Oriol
2
J'aime réellement sortir et entrer.
nderscore
@nderscore Économisez 2 caractères:p=prompt(p().replace(/./g,x=>x^1))
Gaurang Tandon
@GaurangTandon cela devrait être (p=prompt)(p().replace(/./g,x=>x^1))et c'est la même longueur.
nderscore
@nderscore Moi aussi j'ai pensé que c'était comme ça, mais ça a fonctionné sans la parenthèse aussi, étrangement.
Gaurang Tandon
7

Labyrinthe , 6 octets

(Le labyrinthe est plus récent que ce défi, donc cette réponse n'est pas concurrente - ce n'est pas qu'elle gagne de toute façon ...)

1,
.$@

Ce code suppose que STDIN ne contient que les chiffres (en particulier, pas de nouvelle ligne).

Le pointeur d'instruction (IP) commence dans le coin supérieur gauche en allant à droite. Alors qu'il y a des chiffres à lire, il parcourt en boucle étroite le bloc 2x2 de gauche: 1appuyez sur un 1, ,lisez un chiffre, $XOR avec 1 pour alterner le dernier bit, .imprimez le résultat. L'IP prend cette boucle parce que le haut de la pile est positif après le XOR, de sorte qu'il tourne à droite. Quand nous touchons EOF, ,retourne à la -1place. Ensuite, le XOR va céder -2et avec cette valeur négative l’IP tourne à gauche @et le programme se termine.

Cette solution devrait être optimale pour Labyrinth: vous avez besoin ,et .pour une boucle d'E / S et @pour terminer le programme. Vous avez besoin d'au moins deux caractères (ici 1et $) pour basculer le dernier bit. Et vous avez besoin d'au moins une nouvelle ligne pour une boucle pouvant être terminée.

Sauf si ... si nous ignorons STDERR, c'est-à-dire, si nous terminons par une erreur, nous pouvons enregistrer le fichier @et nous n'avons également besoin d'aucun moyen de basculer entre deux chemins. Nous continuons simplement à lire et à imprimer jusqu'à ce que nous essayions accidentellement d'imprimer une valeur négative (la -2). Cela permet au moins deux solutions de 5 octets:

1,
.$
,_1$.
Martin Ender
la source
5

Rubis: 23

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

Code machine de Turing, 32 octets (1 état - 3 couleurs)

Utilisation de la syntaxe de table de règles requise par ce simulateur de MT en ligne. Emprunté à un article que j'ai publié il y a quelques mois sur mon blog d'utilisateur Googology Wiki.

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

Vous pouvez également tester cela en utilisant cette implémentation Java.

SuperJedi224
la source
4

Python 2.x - 44 octets

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

Pourquoi le rendre complexe, ou utiliser des variables tricheuses?

voir
la source
Son possible d'enregistrer des caractères supplémentaires comme ceci: print''.join('1-int(x)'for x in'input()'). Je ne pouvais pas obtenir les backticks dans le code de commentaire, donc les substitué par '.
Willem
@willem Pour référence ultérieure, vous pouvez les échapper avec une barre oblique inverse: `a\`b`-> a`b.
nyuszika7h
@willem Cela ne fonctionne pas pour une entrée commençant par 0 ou supérieure à maxint (en base10).
seequ
Merci @ nyuszika7h et je n'ai pas pensé à ces cas TheRare, votre solution est donc bonne
Willem
@willem Real facile à oublier des choses comme ça. :)
voir le
4

R, 27 caractères

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

Usage:

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

PHP> 5.4 - 37 caractères

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

$s est l'entrée

Try it online

Alireza Fallah
la source
5
Abus intelligent de la <kbd>balise.
nyuszika7h
3

TI-BASIC, 7 octets

Il s'agit d'une fonction qui prend une chaîne binaire (de bout en bout Ans) en entrée et renvoie la sortie sous forme de chaîne inversée (non inversée), comme spécifié. Pour plus d’aide, vous pouvez consulter l’application de liste not(sur le wiki TI-BASIC. J'utilise la version compilée car elle est plus petite:

»*r>Õ¸r

En hex:

BB 2A 72 3E D5 B8 72

Explication

»*r - Prendre la fonction entrée sous forme de chaîne et convertir en liste

> - Pipe liste donnée aux opérateurs suivants

Õ¸r - Retourne l'inverse de la liste

Timtech
la source
quels sont tous les espaces à la fin de »*r>Õ¸r ?
kitcar2000
@ kitcar2000 Oups, j'avais l'habitude d'avoir le HEX après cela. Mais après l'avoir déplacé, j'ai oublié de supprimer les espaces ... Je l'ai fait maintenant.
Timtech
Il devrait être utile de noter que: 1. Sur la calculatrice, cela s’affiche expr(Ans:Returnnot(Ans: 2. {Etant donné que la chaîne n'est pas séparée par des virgules et qu'elle ne commence pas par un , elle sera évaluée en un entier tel que 1000010011 et non en une liste. 3. Returnne fonctionne pas comme vous l'avez écrit; 4. Cela donne la sortie sous forme de liste, pas de chaîne.
lirtosiast
3

Haskell, 22 octets

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

J'ai été surpris par le manque de solutions Haskell à ce défi, alors en voici une. Il est évalué à une fonction qui prend une chaîne et renvoie son inverse.

Explication

Rien d'extraordinaire ici.

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
la source
3

Befunge 93, 25 octets

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

En supposant que la pile vide et EOF lisent -1.

0 pousse un \ 0 en tant que terminateur nul

>~1+:#v_ est une boucle d’entrée, lit ascii, ajoute 1, vérifie si EOF + 1 = 0,

^ -1< sinon, soustrait 1 et laisse la valeur ascii poussée sur la pile.

$>:#,_@ dépose la copie supplémentaire de zéro en haut de la pile, puis imprime la chaîne binaire de haut en bas

Si la pile vide lit 0, sauvegardez 2 octets avec

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

Une version d'environ 15 octets est possible en utilisant le même algorithme si EOF = 0, mais je ne dispose pas d'une telle implémentation pour tester.

sig_seg_v
la source
3

Javascript ES6, 26 caractères

s=>s.replace(/\d/g,x=>x^1)
Qwertiy
la source
3
Pourquoi / \ d / g pas /./g
l4m2
2

Python3, 39

Methinks Python n’est pas le meilleur langage pour cela. :)

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

Si vous souhaitez avoir une nouvelle ligne après la sortie, voici une alternative à 43 caractères:

print(''.join("01"[i<"1"]for i in input()))
DLosc
la source
Code fonctionnera sans end=''juste ,fera :) - à moins que vous souciez d'être là sans espace
Harry Beadle
@ British Color, non, c'est Python2. La printfonction de Python3 nécessite de modifier le endparamètre pour supprimer une nouvelle ligne à la fin de chaque impression. De plus, selon les spécifications de OP, je pense que je tiens à l'absence d'espaces. :) Merci pour le commentaire, cependant!
DLosc
Aww, cool, je ne savais pas ça! Je travaille principalement dans 2.7: /
Harry Beadle
2

J - 11 caractères

Les valeurs booléennes en J sont représentées par les nombres entiers 0et 1, qui sont bien sûr aussi des indices valides dans les tableaux (dans ce cas, le tableau à 2 caractères '01')

'01'{~'0'&=
Dan Bron
la source
Je pense que cette réponse est techniquement plus correcte que la réponse J la plus haute, qui affiche un tableau booléen au lieu d’une chaîne.
Gar
En fait, je n'ai pas remarqué la solution J la mieux classée lorsque j'ai posté (je ne sais pas comment je l'ai manquée, mais c'est ce que j'ai fait). Pour être juste avec cette solution, il est dit explicitement "cela ne fait pas ce que font les autres solutions". BTW, une autre façon d’exprimer cette solution (sortie littérale) en 11 caractères est [:, ": @ = & '' 0 ''.
Dan Bron
Bonjour, merci pour un autre code! Je vais apprendre plus J de vous les gars. À propos de cette déclaration, je pense qu’il faisait référence au signe égal, qu’il compare chaque élément au lieu d’une cession.
Gar
2

C #, 131 octets

Un peu tard pour la fête, mais voici le mien. :)

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

MATLAB, 13 octets

@(x)[97-x '']

Après avoir exécuté ce qui précède, appelez simplement la fonction avec votre chaîne d’entrée pour obtenir la chaîne inversée. Par exemple en cours d'exécution:

ans('10101110101010010100010001010110101001010')

impressions:

01010001010101101011101110101001010110101
Tom Carpenter
la source
2

Moteur Bot , 4x8 = 32

Non compétitif car la langue postdate la question.

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

Avec en surbrillance:

entrez la description de l'image ici

SuperJedi224
la source