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


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.

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! – Grant Miller Feb 24 '18 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}
NSSSN        Create Label_1                  [0]          {49:49}
TNST        Print to STDOUT as integer      []           {49:49}           0

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}
SSSTN        Push 1                          [1,1]        {49:48}
TSST         Subtract (1-1)                  [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

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}
SSSTN        Push 1                          [1,1]        {49:48}
TSST         Subtract (1-1)                  [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

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}
SSSTN        Push 1                          [39,1]       {49:10}
TSST         Subtract (39-1)                 [38]         {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. – Toby Speight Jan 10 '19 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
1x1f1r3x1v2e3x0v0e1s1o1f # Function 1
# Read a byte of input
# 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


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} – Doorknob Jun 9 '14 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') – cfrick Jun 10 '14 at 14:27

JavaScript 56

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


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. – Michael Stern Oct 27 '15 at 21:31
• We count in bytes, not characters. → is 3 bytes. – mbomb007 Sep 16 '16 at 20:07
• And, they're snippets as opposed to functions or complete programs. chat.stackexchange.com/transcript/message/32365215#32365215 – mbomb007 Sep 16 '16 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

Java, 101 bytes

class R{String r(String s){return s.replaceAll("0", "2").replaceAll("1", "0").replaceAll("2", "1");}}


Ungolfed

class R{
String r(String s){
return s.replaceAll("0", "2").replaceAll("1", "0").replaceAll("2", "1");
}
}

• I think you misunderstood the task ... it was not to reverse the order, but to swap 1 and 0. – Paŭlo Ebermann Nov 1 '15 at 2:51
• @PaŭloEbermann, corrected it.. Thanks – The Coder Nov 2 '15 at 4:50

Vitsy, 13 12 Bytes

Byte size reduced by newest version ending execution on end of file*.

I\[i1+2M]l\N
I\             Repeat everything in the [] for input stack's length.
[i1+2M]      Grab an item from the input, add 1 and modulo 2 (to invert the number).
l\    Repeat the next character for the currently active program stack's length.
N   Output the top item of the stack as a number.


*In situations that don't involve special cases.

Pyth, 8 bytes

VwpCxCN1

Vw       for every char in input
CN  compute char code of char
x  1 xor with 1
C     convert from int to char
p      print


pb, 46 bytes (non-competing)

^w[B!0]{w[B=48]{vb[1]^b[0]}>}vw[X!0]{<b[48+B]}


pb is newer than this challenge is, so it can't compete. Oh well.

In pb, the input lives at Y=-1. This program loops over the whole input, putting a 1 below any bytes in the input with a value of 48, or '0'. At the end of the input, it goes back to Y=0 and heads right, adding 48 to everything. Spaces that were left alone become 48=='0', spaces with a 1 value become 49=='1'.

Explained:

^w[B!0]{        # For each byte of input:
w[B=48]{      # While byte == '0':
vb[1]^      # Place a 1 on the canvas below it
b[0]        # Clear input char (just to break loop)
}
>}

vw[X!0]{<       # For each point on the canvas below the input:
b[48+B]       # Add 48 to the existing value (convert digit to ASCII)
}


Beam, 54 bytes

While I having some fun playing with beam, hears the shortest I've managed to do for this one so far. All the unused spaces are a wee bit annoying, but I might be able to compress this a wee bit more.

'''''''>+++++\
v+<--n<rSP(++ /
Hu(<
(@   r^
>@pS r^


Boiled down it compares the the ascii value of STDIN to the ascii value of 1 and decrements if 1 or increments otherwise. It doesn't throw errors or anything if non zeros or ones are encountered.

Try it in the snippet

var ITERS_PER_SEC = 100000;
var TIMEOUT_SECS = 50;
var ERROR_INTERRUPT = "Interrupted by user";
var ERROR_TIMEOUT = "Maximum iterations exceeded";
var ERROR_LOSTINSPACE = "Beam is lost in space";

var code, store, beam, ip_x, ip_y, dir, input_ptr, mem;
var input, timeout, width, iterations, running;

function clear_output() {
document.getElementById("output").value = "";
document.getElementById("stderr").innerHTML = "";
}

function stop() {
running = false;
document.getElementById("run").disabled = false;
document.getElementById("stop").disabled = true;
document.getElementById("clear").disabled = false;
document.getElementById("timeout").disabled = false;
}

function interrupt() {
error(ERROR_INTERRUPT);
}

function error(msg) {
document.getElementById("stderr").innerHTML = msg;
stop();
}

function run() {
clear_output();
document.getElementById("run").disabled = true;
document.getElementById("stop").disabled = false;
document.getElementById("clear").disabled = true;
document.getElementById("input").disabled = false;
document.getElementById("timeout").disabled = false;

code = document.getElementById("code").value;
input = document.getElementById("input").value;
timeout = document.getElementById("timeout").checked;

code = code.split("\n");
width = 0;
for (var i = 0; i < code.length; ++i){
if (code[i].length > width){
width = code[i].length;
}
}
console.log(code);
console.log(width);

running = true;
dir = 0;
ip_x = 0;
ip_y = 0;
input_ptr = 0;
beam = 0;
store = 0;
mem = [];

input = input.split("").map(function (s) {
return s.charCodeAt(0);
});

iterations = 0;

beam_iter();
}

function beam_iter() {
while (running) {
var inst;
try {
inst = code[ip_y][ip_x];
}
catch(err) {
inst = "";
}
switch (inst) {
case ">":
dir = 0;
break;
case "<":
dir = 1;
break;
case "^":
dir = 2;
break;
case "v":
dir = 3;
break;
case "+":
if(++beam > 255)
beam = 0;
break;
case "-":
if(--beam < 0)
beam = 255;
break;
case "@":
document.getElementById("output").value += String.fromCharCode(beam);
break;
case ":":
document.getElementById("output").value += beam;
break;
case "/":
dir ^= 2;
break;
case "\\":
dir ^= 3;
break;
case "!":
if (beam != 0) {
dir ^= 1;
}
break;
case "?":
if (beam == 0) {
dir ^= 1;
}
break;
case "_":
switch (dir) {
case 2:
dir = 3;
break;
case 3:
dir = 2;
break;
}
break;
case "|":
switch (dir) {
case 0:
dir = 1;
break;
case 1:
dir = 0;
break;
}
break;
case "H":
stop();
break;
case "S":
store = beam;
break;
case "L":
beam = store;
break;
case "s":
mem[beam] = store;
break;
case "g":
store = mem[beam];
break;
case "P":
mem[store] = beam;
break;
case "p":
beam = mem[store];
break;
case "u":
if (beam != store) {
dir = 2;
}
break;
case "n":
if (beam != store) {
dir = 3;
}
break;
case "":
--store;
break;
case "'":
++store;
break;
case ")":
if (store != 0) {
dir = 1;
}
break;
case "(":
if (store != 0) {
dir = 0;
}
break;
case "r":
if (input_ptr >= input.length) {
beam = 0;
} else {
beam = input[input_ptr];
++input_ptr;
}
break;
}
// Move instruction pointer
switch (dir) {
case 0:
ip_x++;
break;
case 1:
ip_x--;
break;
case 2:
ip_y--;
break;
case 3:
ip_y++;
break;
}
if (running && (ip_x < 0 || ip_y < 0 || ip_x >= width || ip_y >= code.length)) {
error(ERROR_LOSTINSPACE);
}
++iterations;
if (iterations > ITERS_PER_SEC * TIMEOUT_SECS) {
error(ERROR_TIMEOUT);
}
}
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">Code:
<br>
<textarea id="code" rows="8" style="overflow:scroll;overflow-x:hidden;width:90%;">'''''''>+++++\
v+<--n<rSP(++ /
Hu(<
(@   r^
>@pS r^</textarea>
<br>Input:
<br>
<textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">10101110101010010100010001010110101001010</textarea>
<p>Timeout:
<input id="timeout" type="checkbox" checked="checked">&nbsp;
<br>
<br>
<input id="run" type="button" value="Run" onclick="run()">
<input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="disabled">
<input id="clear" type="button" value="Clear" onclick="clear_output()">&nbsp; <span id="stderr" style="color:red"></span>
</p>Output:
<br>
<textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
</div>

Javascript, 81 Bytes:

function(s){return s.replace(/1/g,'a').replace(/0/g,'b').replace(/a/g,0).replace(/b/g,1)}


Test

=>"1001101"

<="0110010"

• function(s){return s.replace(/1/g,'a').replace(/0/g,'1').replace(/a/g,'0')} is shorter. – mbomb007 Sep 16 '16 at 20:00
• @mbomb007 Oh thanks! I didn't notice that redundancy in mine. Mind if I add that to my original post? – Fuzzyzilla Sep 17 '16 at 21:34

TeaScript, 8 bytes

xl(#l^1)

x       //input
l(#    //loops through every character of the input
l^1 //find the inverse of each character
)


Try it online at its online interpreter (DOES NOT WORK IN CHROME).

• With TeaScript 3 this can be xl#l^1 – Downgoat Feb 5 '16 at 5:34

Clojure, 41 bytes

(fn[b](apply str(map #(if(= %\1)\0\1)b)))


Hoon, 34 bytes

|*(* tape(turn +< (cury mix 1)))


Stole Dennis' method for using char xor 1 to switch between '0' and '1'.

Return a gate that maps over the tape given, and calls (mix n 1) (binary xor) for each element, then cast the resulting list back to a tape.

In Hoon, the entire memory model is a binary tree of bignums. All code is evaluated on this tree, called the 'subject'. +< is "tree navigation syntax"; instead of specifying a name for the compiler to resolve into an axis of the subject, you can provide the axis yourself with alternating characters of +/- and </> to walk the tree. Code within a gate is evaluated on a subject that has the arguments it was called with placed at +<, so we can reference the arguments directly without having to assign a name to them.

|* creates a wet gate, essentially a generic function, that is typechecked at the callsite with a monomorphized version of the gate. This lets us use * as the sample for the gate instead of having to use |=(tape code) - as long as the type of the arguments at the callee are a valid list, so that ++turn typechecks.

> %.  "10101110101010010100010001010110101001010"
|*(* tape(turn +< (cury mix 1)))
"01010001010101101011101110101001010110101"

• Answers using languages and language features that are newer than the challenge are not allowed and must be marked "non-competing". Is anything you're using from newer than Jun 7 '14 at 20:20? github.com/urbit/urbit/commits/master?page=48 – mbomb007 Sep 16 '16 at 19:56
• @mbomb007 I first started using Urbit on 9/28/14, and the only major Hoon update was recently (164k to 151k), which doesn't affect that snippet. I'll have to check, but I'm quite sure that this is valid. – RenderSettings Sep 19 '16 at 18:00

𝔼𝕊𝕄𝕚𝕟, 13 chars / 23 bytes (non-competing)

ô⟦ï]ć⇝a^1)ø⬯)
`

Try it here (Firefox only).

• I think this is technically invalid, because the language was invented after the challenge. – lirtosiast Oct 28 '15 at 5:27
• But it doesn't have any advantage specific to the challenge... – Mama Fun Roll Oct 28 '15 at 13:37