# The shortest code to invert bit-wise a binary string

Me thinks there aren't enough easy questions on here that beginners can attempt!

The challenge: Given a random input string of 1's and 0's such as:

10101110101010010100010001010110101001010


Write the shortest code that outputs the bit-wise inverse like so:

01010001010101101011101110101001010110101


# Pyth, 6 bytes

jkms!s

Try it!

Takes input as a string. New at this so it probably isn't optimal but the shortest pyth one here so far!

# Cubix, 12 bytes

i?./^\'1c$@O  Try it online! cube form:  i ? . / ^ \ ' 1 c$ @ O
. . . . . . . .
. .
. .


# Sinclair ZX81, Timex TS1000/1500, ~60 tokenized BASIC bytes

 1 INPUT A$2 PRINT A$
3 FOR I=1 TO LEN A$4 PRINT NOT VAL A$(I);
5 NEXT I


This technique iterates over each byte of the string, taking it's numeric value and printing the NOT equivalent. In ZX81 terms, NOT 1 is 0 and NOT 0 is 1. RUN the program and enter your binary string, followed by NEW LINE (or the Enter key).

Simple test case shown below.

# Excel, 51 bytes

Performs 3 substitutions: 0 -> 5, 1 -> 0, 5 -> 1

=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,0,5),1,0),5,1)


For fun, replacing the third substitution (5 -> 1) eith a /5 works for input where first character is 0. But for others, need to pad with for length. Resulting in 59 bytes:

=TEXT(SUBSTITUTE(SUBSTITUTE(A1,0,5),1,0)/5,REPT(0,LEN(A1)))


## Pure Bash shell solution. 87 bytes.

while((n<=${#1}));do case "${1:$n:1}" in 0)printf 1;;1)printf 0;; esac;n=$((n+1));done

• Welcome to PPCG! Nice first solution! Commented Feb 24, 2018 at 11:14

# Perl 6, 11 bytes

{TR/10/01/}


Try it online!

Simple transliterate that turns all 1s to 0s and vice-versa.

# 05AB1E, 3 bytes

€_J


Explanation:

€      # Map over the digits of the (implicit) input
_     #  Negative boolean: 0 becomes 1, everything else (so the 1s) becomes 0
J    # After the map, join everything together (and output implicitly)


# Whitespace, 79 bytes

[N
S S N
_Create_Label_LOOP][S S S T T   S S S T N
_Push_49][S N
S _Duplicate_49][S N
S _Duplicate_49][T  N
T   S _Read_STDIN_as_character][T   T   T   _Retrieve][T    S S T   _Subtract][S N
S _Duplicate][N
T   S S N
_If_0_Jump_to_Label_1][S S S T  N
_Push_1][T  S S T   _Subtract][N
T   S T N
_If_0_Jump_to_Label_0][N
N
N
_Exit][N
S S T   N
_Create_Label_0][S S S T    N
_Push_1][N
S S S N
_Create_Label_1][T  N
S T _Print_integer_to_STDOUT][N
S N
N
_Jump_to_Label_LOOP]


Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Since Whitespace can only take input as integer or character, we must add a trailing character (other than 0 or 1; like a newline, space, a letter, etc.) to indicate we're done with the input-string after reading it character by character.

Try it online (with raw spaces, tabs and new-lines only).

Example run: input = 100

Command       Explanation                     Stack        Heap      STDIN   STDOUT

NSSN          Create Label_LOOP               []
SSSTTSSSTN   Push 49                         [49]
SNS          Duplicate 49                    [49,49]
SNS          Duplicate 49                    [49,49,49]
TNTS         Read STDIN as character         [49,49]      {49:49}   1
TTT          Retrieve                        [49,49]      {49:49}
TSST         Subtract (49-49)                [0]          {49:49}
SNS          Duplicate 0                     [0,0]        {49:49}
NTSSN        If 0: Jump to Label_1           [0]          {49:49}
NSSSN        Create Label_1                  [0]          {49:49}
TNST        Print to STDOUT as integer      []           {49:49}           0
NSNN        Jump to Label_LOOP              []           {49:49}

SSSTTSSSTN   Push 49                         [49]
SNS          Duplicate 49                    [49,49]
SNS          Duplicate 49                    [49,49,49]
TNTS         Read STDIN as character         [49,49]      {49:48}   0
TTT          Retrieve                        [49,48]      {49:48}
TSST         Subtract (49-49)                [1]          {49:48}
SNS          Duplicate 0                     [1,1]        {49:48}
NTSSN        If 0: Jump to Label_1           [1]          {49:48}
SSSTN        Push 1                          [1,1]        {49:48}
TSST         Subtract (1-1)                  [0]          {49:48}
NTSTN        If 0: Jump to Label_0           []           {49:48}

NSSTN        Create Label_0                  []           {49:48}
SSSTN       Push 1                          [1]          {49:48}
NSSSN       Create Label_1                  [1]          {49:48}
TNST        Print to STDOUT as integer      []           {49:48}           1
NSNN        Jump to Label_LOOP              []           {49:48}

SSSTTSSSTN   Push 49                         [49]
SNS          Duplicate 49                    [49,49]
SNS          Duplicate 49                    [49,49,49]
TNTS         Read STDIN as character         [49,49]      {49:48}   0
TTT          Retrieve                        [49,48]      {49:48}
TSST         Subtract (49-49)                [1]          {49:48}
SNS          Duplicate 0                     [1,1]        {49:48}
NTSSN        If 0: Jump to Label_1           [1]          {49:48}
SSSTN        Push 1                          [1,1]        {49:48}
TSST         Subtract (1-1)                  [0]          {49:48}
NTSTN        If 0: Jump to Label_0           []           {49:48}

NSSTN        Create Label_0                  []           {49:48}
SSSTN       Push 1                          [1]          {49:48}
NSSSN       Create Label_1                  [1]          {49:48}
TNST        Print to STDOUT as integer      []           {49:48}           1
NSNN        Jump to Label_LOOP              []           {49:48}

SSSTTSSSTN   Push 49                         [49]
SNS          Duplicate 49                    [49,49]
SNS          Duplicate 49                    [49,49,49]
TNTS         Read STDIN as character         [49,49]      {49:10}   \n
TTT          Retrieve                        [49,10]      {49:10}
TSST         Subtract (49-10)                [39]         {49:10}
SNS          Duplicate 39                    [39,39]      {49:10}
NTSSN        If 0: Jump to Label_1           [39]         {49:10}
SSSTN        Push 1                          [39,1]       {49:10}
TSST         Subtract (39-1)                 [38]         {49:10}
NTSTN        If 0: Jump to Label_0           []           {49:10}
NNN          Exit program                    []           {49:10}


# C, 34 bytes

Fully portable (not just one or two character encodings).

f(char*s){for(;*s;)*s++^='0'^'1';}


Output is in-place modification of the string.

A less portable version would use a simple number in place of the expression '0'^'1' - e.g. 1 for ASCII or EBCDIC - saving up to 6 bytes.

# Demo

#include<stdio.h>
int main(void)
{
char s[] = "10101110101010010100010001010110101001010";
f(s);
printf("%s\n", s);
}

• Did you at all read the answer? I did say that you could use 1 for ASCII or EBCDIC systems, but that's not fully portable. Commented Jan 10, 2019 at 17:04

# Reticular, 15 bytes

iSBql[n1~-o]~*;


Try it online!

## Explanation

i               # Read input as string.
S              # Push array of characters in the string.
B             # Push every character in the array to the stack.
q            # Reverse the stack.
l           # Push the size of the stack.
[     ]    # Push a function that does the following:
n         # Convert top of stack to int.
1~-      # Push 1, swap the top two items in the stack and subtract them.
This takes a character x in the input string to 1-x, resulting in the bit negation.
o     # Output the top item of the stack
~   # Swap the top two items in the stack.
*  # Call the above function the same number of times as length of the input string.
(That is, for each bit in the input string, negate the bit and output it.)
; # Exit


# Zsh, 3230 29 bytes

Shell builtins only: specifically, the XOR operator ^.

29 bytes: <<<$[1&#1^1]${1:+$0${1:1}}     recursion, by @GammaFunction
30 bytes: for X (${(s::)1})printf$[1^X]   more efficient for, by @GammaFunction
32 bytes: for X in ${(s::)1};printf$[1^X]

# Bash, 35 bytes

35 bytes: echo $[1^${1:0:1}]${1:+$0 ${1:1}} recursion, by @GammaFunction 44 bytes: for((;i<${#1};i++));{ printf $[1^${1:i:1}];}

# naz, 62 bytes

2a2x1v4a8m2x0v1x0f1a1o1f0x1x1f1r3x1v2e3x0v0e1s1o1f0x1x2f0a0x1f


Works for any input file of 1's and 0's terminated with the control character STX (U+0002).

Explanation (with 0x commands removed)

2a2x1v                   # Set variable 1 equal to 2
4a8m2x0v                 # Set variable 0 equal to 48
1x0f1a1o1f               # Function 0
# Add 1 to the register, output, then jump to function 1
1x1f1r3x1v2e3x0v0e1s1o1f # Function 1
# Read a byte of input
# Jump to function 2 if it equals variable 1
# Jump to function 0 if it equals variable 0
# Otherwise, subtract 1 from the register, output,
# then jump back to the start of function 1
1x2f0a                   # Function 2
# Add 0 to the register
1f                       # Call function 1


# Vyxal, 1 byte

†


Try it Online!

# Seed, 4001 bytes

12 22467800860124070178830737520017462583858242261688818083563967964459492073122807697499205500520814270057390910850070898023779372337845606451434999597324513116009103282793138363889251070541548956324245082329674394635061703600124082725719347051922338244963555154324370355238030226191755446700141538448744882828401289257105544925638425778005923480537339123570198316859318125063896435356052960878798108984454300034802385262580209301524236136248719519921946031828718409466542238635588879942564163080889109125277745199171883349061520869997942949639546109688688788190940395919772174262841234098191606390237829497693620421210677789981161937899626045826080802574655497452130041254940986107805698757014260882449573944556602129769737703315763962652354056343895230431267996034382053925203053307001003333804173344801825634791820695141553355621023990400711189803634409496082889140704419749000824286397618093636247662749951187708752873519950104578968340972361618524412325645098713699731021088671725575084245344751522649567245480821120339220564646068943031946783303903697367253955714044444736783957222575572241319818457276409266126595415669073513253183989135440889608714964831521757016620819816850763183162405901035026179418588534822021105457990128662024405359920540011554379532044740831623941815066395865241509740805855343347903491296220782048364612164349265833607844707347159345067371895976293721572188715573401930387350648051542907586789168439477137453524755084958277596405623536912666957589117645881846750438246766165234099806368247856450957646185589082789378547512134409783416060602945874310445999221638049305359530033182401798760305340764937308446248612494477798147335809113299917339976366532774445821809050635734106638274070832257786599315353165493685027605339636316348551394743274112960759253605959515456316478044100123168731682979291374569338572092082869123150387567271191092971638844368321984656886356084605909222030710150000407927489274727063860328145859688080273381880596439423213732909155412724144303878876832255238035073247552082203299616735975900731438704855017567941085339636443620043767639365385673296669965015825191217275207514003602363380064736873151800792178445714348743862550536432711191527537777366511426388278812825671029910854980928682139046501881451902927544724305377340163929216935010743857978836424566071713806944632017276688837315532946743339777915616030011161708954637903288482182308670771005462983742584744344066707662057998285468364681750429465060696832417939697844369858677491150502866685111618816518160802785248209223095658989030839275159107736257541077894710268795690490482316124636074318996932638195319298458661969220607094970584356214121664089841491446209143755531268896976923041463145479413553581327439998726678121104922190297288358873060196647710463668580909699483989882954140817314685815779877890795712718361623431063616953603383264989936053474641614569529053703569694229770237259956181704387417633362063048253194547238628479951576197180647512354097114011449776247632199450163435658817379247320758050414702476804424429759571774687799269847272241040125929986561154071306898735707411802043172870573801610582124052361577796587449450980584367871604033018651000439099472710719881306790290886915898325194141014611846079395667807264562687901178526268969175193051163108905837484413417816154510711926841899863006227166207619380521870269028440296101561963248505036429083164400024679203296550171382565396820939898890114978768872643479708314697168816959694732131149657059289619022081777426733646802338248337315031956161258755974424581432365955447254124547801478393685789570178512768654602326030764253268669713151354485782078002288517388185165706102804594623909510752146365156058948091625484531645749465785838573681651816640209540090471551546428418684230905961729447735111300809970327136013512273479286642147001855525584783017763430816620169651297763121245380125111624755448069360703085235290573427681024676161302183767200167011805149778397302405685676191974385732998259279459936937214011


Doesn't work on TIO.

# Julia, 29 bytes

x->replace(x,'0'=>'1','1'=>0)


Attempt This Online!

Julia also has the operator ~ for bitwise not:

julia> x=0b10101110101010010100010001010110101001010
0x0000015d5288ad4a

julia> bitstring(x)
"0000000000000000000000010101110101010010100010001010110101001010"

julia> bitstring(~x)
"1111111111111111111111101010001010101101011101110101001010110101"
$$$$


# BitBitJump-16, 61 bytes

-1 96
-1 87
22 -1
87 -1
-1 -1
-1 -1
-1 -1
-1 -1
-1 -1
-1 -1 0


TIO doesn't allow passing arguments to the compiler so I called the program manually.

Try it online!

16-bit mode is not very useful outside of minimizing offsets because self-modifying code is unable to encode a negative offset. This is because in all word sizes, the offsets are read stored in an int32 array and they are not properly sign extended unless the source was sign extended.

So for example, if I do

    .include lib.bbj

.copy A, B
A:0 B:-1


The result will be this:

    A:65535 B:-1


The code expects a string followed by a newline.

Explained:

    # Read bit 0 from stdin to "x"
L:-1   i:x
# Store bit 1 to bit 7 of the jump offset of this instruction.
# When '\n' (00001010), bit 1 will be set and instead of jumping to the next
# instruction (96), it will jump to e (224)
-1     j'7     j:?
# Bits [7:6] of i are 01. When the first bit of stdin is copied here,
# it will either target i'6 or i'7.
# It basically becomes {1, 0}[i], flipping the bit.
x:i'6    -1
# When the IP interprets e, it sees -1, 240, -1, which exits.
#   -1 240 -1
j'7  e:-1
# Copy the rest of stdin to stdout
-1     -1
-1     -1
-1     -1
-1     -1
-1     -1
# Loop
-1     -1    L


This code compiles to this.

-1 96 48    # 1111111111111111 0000000001100000 0000000000110000
-1 87 96    # 1111111111111111 0000000001010111 0000000001100000
22 -1 144   # 0000000000010110 1111111111111111 0000000010010000
87 -1 192   # 0000000001010111 1111111111111111 0000000011000000
-1 -1 240   # 1111111111111111 1111111111111111 0000000011110000
-1 -1 288   # 1111111111111111 1111111111111111 0000000100100000
-1 -1 336   # 1111111111111111 1111111111111111 0000000101010000
-1 -1 384   # 1111111111111111 1111111111111111 0000000110000000
-1 -1 432   # 1111111111111111 1111111111111111 0000000110110000
-1 -1 0     # 1111111111111111 1111111111111111 0000000000000000


# Julia, 20 bytes

x->join('1'.-[x...])


Attempt This Online!

-4 bytes thanks to Steffan

• 22 bytes: x->@. "01"['2'-[x...]] Commented Nov 22, 2022 at 17:28
• Actually this works for 20: x->join('1'.-[x...]) Commented Nov 22, 2022 at 17:30

# Thunno 2B, 3 bytes

1Æ^


Attempt This Online!

Inspired by Dennis's GolfScript answer.

#### Explanation

The B flag does most of the heavy-lifting here.

    # Implicit input. The B flag converts the
# input string to a list of codepoints.
1Æ^ # Compute the bitwise XOR of each codepoint
# with 1, so 48 -> 49 and 49 -> 48
# Implicit output. The B flag converts the
# integer list to a string.


# 05AB1E, 1 byte

_


Try it online! Beats all other answers. Takes I/O as a list of bits.

_  # full program
_  # logically negate...
# (implicit) each element of...
# implicit input
# implicit output

• Congratulations :) Commented Jun 12, 2021 at 12:16

## Scala, 33 bytes

print(readLine map(c=>"10"(c&1)))


# Ruby, 37 32

$*[0].each_char{|x|p x==?0?1:0}  • 32: $*[0].each_char{|x|p x==?0?1:0} Commented Jun 9, 2014 at 13:35

# Powershell 41

(($args-split''-ne'')|%{1-bxor$_})-join''


Explanation:

It reads the input and splits it to turn it into an array. Then it iterates through every element of the array and uses the bitwise exclusive or to turn 1 to 0 and 0 to 1, and then joins the result and prints it to console...

## Batch - 167 Bytes

@echo off&setlocal enabledelayedexpansion&set l=-1&set s=%~1&set o=%~1
:c
if defined s set/al+=1&set s=%s:~1%&goto c
for /l %%a in (%l%,-1,0)do set/p=!o:~%%a,1!<nul


Could be cut down a bit by using Powershell to get the length of the input - then again, it could be cut down a lot by using a different language.

## Python 3 - 50 bytes

r=str.replace
r(r(r(input(),'1','a'),'0','1'),'a','0')


It's not as short as some of the other ones, but it takes a different approach.

# php, 41 bytes

Where $s is the string: str_replace(array(1,0,2),array(2,1,0),$s)


This works because the str_replace() function is just a loop when given an array. This works like this:

• replace all 1 with 2
• then all 0 with 1
• then the 2 back to 0

## Groovy - 31 28 chars

edit thanks to cfrick's insightful comment:

print args[0].tr("01","10")


previous:

args[0].each{print it=="1"?0:1}

• groovy also has tr. e.g. b.tr('01','10') Commented Jun 10, 2014 at 14:27

# JavaScript 56

a=prompt()
for(b='',r=/./g;c=r.exec(a);b+=c^1);
alert(b)


## Mathematica / Wolfram Language

Three solutions here, all of which assume that the argument is being passed as a string in a variable "b". If it is being passed in another format (as I think some of the other solutions here assume), shorter solutions are possible.

Method 1, using bitwise operator for 64 char

StringJoin[ToString[BitNot[#] + 2] & /@ ToExpression[Characters@b]]


Method 2 using If/Then for 45 char

StringJoin[If[# == "0", "1", "0"] & /@ Characters@b]


Method 3, operating directly on the string, for 34 char

StringReplace[b, {"0" -> "1", "1" -> "0"}]


I suspect some Mathematica wizard is going to breeze in here and do it in 15 bytes.

• @FryAmTheEggman within Mathematica, each of the -> right arrows become single →s. My character count is correct. Mathematica preps copied code for pasting by adding spaces and replacing Unicode with ASCII characters, hence the representation above. Commented Oct 27, 2015 at 21:31
• We count in bytes, not characters. → is 3 bytes. Commented Sep 16, 2016 at 20:07
• And, they're snippets as opposed to functions or complete programs. chat.stackexchange.com/transcript/message/32365215#32365215 Commented Sep 16, 2016 at 20:35

# C, 42 bytes

main(c){for(;c=~getchar();putchar(~c^1));}


# Ruby, 48 bytes

\$<.each_char{|i|print (i.ord-1).chr.gsub"/","1"}
`

Not the shortest, but somewhat interesting