String to Bit Transition

Given an input string of one or more ASCII characters which codepoints are between 0 and 128 (exclusive), do the following:

1. Convert each character into its 7-bit ASCII code (if the ASCII code is less than 7 bits, put leading zero bits)
2. Concatenate all bits (this results in 7*n bits where n is the number of characters)
3. For each bit in this bitstream, print 1 if it is different from the previous bit, and print 0 otherwise. The first output bit is always 1.

Example

Input:

Hi


Output:

11011001011101


Explanation:

The string "Hi" has the ASCII codes

72 105

which in bits are:

1001000 1101001

And the transition bits indicators:

11011001011101

This is code golf. Lowest byte count wins.

Test Cases

Test case 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001


Test case 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111


Test case 3 (credit to Luis Mendo):

##
11100101110010


Congrats to Luis Mendo for the shortest solution with 9 bytes in MATL!

• Suggested test case ## (leading 0 bit; some answers currently fail because of that) – Luis Mendo Jul 10 '19 at 9:25
• How is this a duplicate of the Manchester encoding challenge? Am I missing something? – gastropner Jul 10 '19 at 10:25
• The other challenge says converting an input stream of bits into a double-rate output stream, with each input '1' translated to a '01' and each input '0' translated to a '10'. So not dupe in my opinion. If a large number of people upvote @gastropner's comment above I can un-dupe (or any other user with that ability) – Luis Mendo Jul 10 '19 at 11:24
• @Shaggy: Both test cases include a space, which has only a single bit set, and not the 7th. So I don't think the problem statement is guaranteeing that each ascii code will be exactly 7 bits in length. – recursive Jul 10 '19 at 15:05
• @SmileAndNod On second thought, I think you don't need to handle empty string. – justhalf Jul 17 '19 at 21:47

MATL, 9 bytes

Hj7&B!hdg


Try it online!

Explanation

H     % Push 2
j     % Read line of input, unevaluated
7&B   % Convert to binary with 7 bits. Gives a 7-column matrix
!     % Transpose
h     % Concatenate horiontally. The matrix is read in column-major order
d     % Consecutive differences
g     % Convert to logical. Implicitly display

• This is the shortest so far. +1. It's fun to have a built-in for consecutive differences. – justhalf Jul 12 '19 at 5:19

Python 2, 58 bytes

n=1
for c in input():n=n<<7|ord(c)
print'1'+bin(n^n/2)[4:]


Try it online!

Japt-P, 11 bytes

Takes advantage of the fact that spaces can be coerced to 0 in JavaScript when trying to perform a mathematical or, in this case, bitwise operation on it.

c_¤ù7Ãä^ i1

c_¤ù7Ãä^ i1     :Implicit input of string
c_              :Map codepoints
¤             :  Convert to binary string
ù7           :  Left pad with spaces to length 7
Ã          :End map
ä^        :XOR consecutive pairs
i1     :Prepend 1
:Implicitly join and output

• The 7-bit means that if it is 32 (for space character), it would be 0100000. Also the % character (37) would be 0100101 – justhalf Jul 10 '19 at 16:58
• It's working now. +1 – justhalf Jul 10 '19 at 17:04

CJam, 21 bytes

1q{i2b7Te[}%e__(;.^);


Try it online!

Explanation

Showing the stack with a sample input of 5:

1 q      e# Push 1 and then the whole input: 1 "5"
{
i      e# Convert to its char code: 1 [53]
2 b    e# Convert to binary: 1 [[1 1 0 1 0 1]]
7 T e[ e# Left-pad with 0 to length 7: 1 [[0 1 1 0 1 0 1]]
} %      e# Map this block over every character in the string
e_       e# Flatten array: 1 [0 1 1 0 1 0 1]
_ ( ;    e# Duplicate array and remove its first element: 1 [0 1 1 0 1 0 1] [1 1 0 1 0 1]
. ^      e# Element-wise xor: 1 [1 0 1 1 1 1 1]
) ;      e# Remove and pop the last element of the array: 1 [1 0 1 1 1 1]
e# Stack implicitly printed: 1101111


To see if a bit is different from the previous bit, we do a vector (element-wise) xor between the bit array and the bit array without the first element. We also remove the last bit of the result, because it is always the last bit of the longer array unchanged.

APL (Dyalog Unicode), 16 bytesSBCS

Full program. Prompts for string from stdin.

1,2≠/∊1↓¨11⎕DR¨⍞


Try it online!

⍞ prompt for input ("a quote in a console")

11⎕DR¨ change each character to bit-Boolean Data Representation

1↓¨ drop the first bit from each

∊ϵnlist (flatten)

2≠/ pairwise difference

1, prepend a one

Jelly, 12 bytes

O+Ø⁷BḊ€FIA1;


Try it online!

Charcoal, 25 bytes

⭆θ◧⍘℅ι²¦⁷←Ｗⅈ←Ｉ﹪⍘ＫＤ²←01 ²1


Try it online! Link is to verbose version of code. Explanation:

⭆θ◧⍘℅ι²¦⁷←


Convert all the characters to binary and pad them to a length of 7 and then print them, but leave the cursor over the last digit.

Ｗⅈ


Repeat until the cursor is over the first digit.

←Ｉ﹪⍘ＫＤ²←01 ²


Calculate whether the digits are different and overwrite each digit with the difference.

1


Overwrite the first digit with a 1.

$args|%{$b=+$_ 6..0}|%{+($c-ne($c=($b-shr$_)%2))}  Try it online! -17 bytes thanks to mazzy :) • – mazzy Jul 10 '19 at 15:52 • Awesome, you have to post it yourself. – Andrei Odegov Jul 10 '19 at 16:50 • this answer for you. my princess is in another castle :)))) – mazzy Jul 10 '19 at 16:56 • @mazzy, some more -7 bytes :) – Andrei Odegov Jul 10 '19 at 23:08 • awesome and brilliant! 【ツ】 – mazzy Jul 11 '19 at 4:41 Ruby-p, 68 57 bytes -11 bytes by shamelessly stealing the method used by xnor's Python solution. l=1 gsub(/./){l=l<<7|$&.ord}
$_=?1+(l^l/2).to_s(2)[2..-1]  Try it online! Original solution: gsub(/./){'%07b'%$&.ord}
l=p
gsub(/./){b=$&.ord-48;r=l ?l^b:1;l=b;r}  Try it online! Octave, 36 30 bytes Fix thanks to Luis Mendo -2 bytes thanks to Sanchises @(a)[1;~~diff(de2bi(a,7)'(:))]  Try it online! • You can probably shave off quite a few bytes with de2bi. – Sanchises Jul 13 '19 at 12:18 • Wasn't working for me before @sanchises but I'll take another look when I can – Expired Data Jul 13 '19 at 12:23 • Try it online! – Sanchises Jul 13 '19 at 15:08 Python 2, 104 bytes lambda w:reduce(lambda(A,P),C:(A+'10'[P==C],C),bin(reduce(lambda a,c:a*128+ord(c),w,1))[3:],('','x'))[0]  Try it online! A quick stab at it. • Clever trick with a*128+ord(c)! But isn't the reduce and lambda kind of costly? – justhalf Jul 10 '19 at 3:54 Dart, 213 168 bytes f(s,{t,i}){t=s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList();for(i=t.length-1;i>0;i--)t[i]=t[i]==t[i-1]?'0':'1';t[0]='1';return t.join();}  Previous one-liner f(String s)=>'1'+s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList().reversed.reduce((p,e)=>p.substring(0,p.length-1)+(p[p.length-1]==e?'0':'1')+e).split('').reversed.join().substring(1);  Try it online! This verbosity and lack of easy built ins is really killing this one. Still managed to pull a one liner though. • -45 bytes by not using a one liner and using a for loop Stax, 13 12 bytes ìEÖâU₧(~¬8IE  Run and debug it If it's guaranteed that all input characters have the 7th bit set, as some answers assume, it can be done in 10 bytes Kotlin, 182 bytes var l='6' fun f(b:String)=b.fold(""){t,i->t+"".a(i.toInt())}.map{if(l==it){l=it;0} else {l=it;1}} fun String.a(v:Int):String=if(v<=0)"${this}0".reversed() else "${this}${v%2}".a(v/2)


Try it online!

Hopefully I can improve this soon, I feel like there must be some spots for improvement but I can't think right now

s/./sprintf'%07b',ord$&/ge;s/.(?=(.))/0|$&^$1/ge;s/^/1/;chop  Try it online! C (gcc (MinGW)), 90 bytes Requires a compiler providing itoa(). n[9],b,c;f(char*s){for(b=*s<64;c=*s++;printf("%07s",itoa((c^c/2)&127,n,2)))c|=b<<7,b=c&1;}  Ruby-p, 50 bytes gsub(/./){"%07b"%$&.ord}
gsub(/./){$=~/#$&$/?0:1}  Try it online! Explanation First line, same as Value Ink's answer: gsub(/./){$&    }   # Replace each character $&… .ord # …with its ASCII code… % # …formatted as… "%07b" # …binary digits padded to 7 places.  Second line: gsub(/./){$&      }  # Replace each character $&…$               # …if the text to its left…
=~             # …matches…
/#  $/ # …the Regexp /c$/ where "c" is the character…
?0:1   # …with 0, or 1 otherwise.


In Ruby you can use interpolation in Regexp literals, e.g. /Hello #{name}/, and for variables that start with $ or @ you can omit the curly braces, so if e.g. $& is "0" then the grawlixy /#$&$/ becomes /0$/. K (ngn/k), 9 13 bytes Solution: ~=':,/(7#2)\'  Try it online! Explanation: ~=':,/(7#2)\' / the solution \' / convert each ( ) / do this together 7#2 / 2 2 2 2 2 2 2 ,/ / flatten =': / equal to each-previous? ~ / not  Notes: • +4 bytes to support strings consisting only of 6-bit chars • This seems to fail for input # for example (output only has 6 bits) – Luis Mendo Jul 10 '19 at 9:19 • @streetster, do you want to post the fixed version? – justhalf Jul 11 '19 at 14:18 Emojicode, 263 bytes 🏁🍇🔤🔤➡️🖍🆕s🔂b📇🆕🔡👂🏼❗️❗️🍇🍪s🔪🔡🔢b❗️➕128 2❗️1 7❗️🍪➡️🖍s🍉🔤?🔤➡️🖍🆕p🔂b s🍇↪️b🙌p🍇👄🔤0🔤❗️🍉🙅🍇👄🔤1🔤❗️🍉b➡️🖍p🍉🍉  Try it online here. Ungolfed: 🏁 🍇 💭 Main code block 🔤🔤 ➡️ 🖍 🆕 s 💭 Start with s as the empty string 🔂 b 📇 🆕 🔡 👂🏼 💭 For each byte b in the input ... ❗️ ❗️ 🍇 🍪 s 💭 ... append ... 🔪 🔡 🔢 b ❗️ ➕ 128 💭 ... b + 128 (this gives the leading zero(s) in case the binary representation of b is shorter than 7 digits) ... 2 💭 ... in binary ... ❗️ 1 7 💭 ... without the leading one ... ❗️ 🍪 ➡️ 🖍 s 💭 ... to s 🍉 🔤?🔤 ➡️ 🖍 🆕 p 💭 This will be used as the previous character, by assigning it neither 0 nor 1 we assure the first bit output is always a one 🔂 b s 🍇 💭 For each character in s: ↪️ b 🙌 p 🍇 💭 If it is the same as the previous character ... 👄 🔤0🔤 ❗️ 💭 ... output a zero ... 🍉 🙅 🍇 💭 ... else ... 👄 🔤1🔤 ❗️ 💭 ... output a one 🍉 b ➡️ 🖍 p 💭 And the current character becomes the new previous character. 🍉 🍉  JavaScript (V8), 150 95 bytes -55 thanks to @dana x=>[...[...x].reduce((a,c)=>a+c.charCodeAt(0).toString(2).padStart(7,0),"")].map(c=>x!=(x=c)|0)  Try it online! Python3.8, 72 bytes Solution: lambda a:["10"[a==(a:=x)]for x in"".join(bin(ord(i)+128)[3:]for i in a)]  Explanation: Ever since Python 3.8 introduced assignment expressions (rather than the standard assignment statements), I have wanted to use them in a list comprehension that needs to remember the last item. This is not the best way to do this but demonstrates an interesting method of using the assignment expression. The code creates a lambda function which takes the required argument which is the string to convert. When called, the function proceeds as follows. Every character in a is converted to its character code which 128 is added to for dealing with 6-bit characters (the binary representation will always be 8 bits and we can chop off the first bit). This number is converted to binary and the header (0x) and the initial 1 from adding 128 is chopped off. These new strings are then joined into one larger string. For each character in this new string (which contains the concatenated 7-bit representation of the text), it is checked if the character is the same as the previous character. What happens with the first character? The first result character should always be "1" so we just have to make sure that whatever is in the last character variable is neither "1" nor "0". We do this by reusing the original parameter now that we are not using it anymore. This may be a problem if the original string was a single "0" (a single "1" just happens to work) but we will ignore that. During the comparison, the previous character was evaluated first so when we use the assignment expression to set the previous character variable to the current character, it does not affect the comparison expressions' evaluation. The comparison either produces True or False which can also be used as 1 or 0 respectively in Python, so they are used to look up either a "1" or "0" in a string • You can save some bytes by using string format literals: bin(ord(i)+128)[3:] -> f"{ord(i):07b}" – movatica Jul 25 '19 at 10:02 Tcl, 215167 140 bytes {{s {B binary} {X ~$w/64}} {join [lmap c [split $s {}] {$B scan $c c w;$B scan [$B format i [expr 2*$w^$w^$X<<7]] B7 r;set X $w;set r}] ""}}  Try it online! Uses shift-by-one and exclusive-or to detect transitions. Carries lsb of current character to msb of next character. Combines output for each character by joining list returned by lmap. Uses lambdas with default arguments to save bytes on initialization and repeated commands. Relies heavily on order of operation. Works for empty string. 05AB1E (legacy), 12 bytes Çb7jð0:¥ÄJ1ì  Uses the legacy version of 05AB1E, since j implicitly joins the strings together, which requires an explicit J after the j in the new version of 05AB1E. Explanation: Ç # Convert the (implicit) input-string to a list of ASCII code-points # i.e. "Hi#" → [72,105,35] b # Convert each integer to a binary string # → ["1001000","1101001","100011"] 7j # Prepend each with spaces to make them length 7, # and join everything together to a single string implicitly # → "10010001101001 100011" ð0: # Replace all those spaces with 0s # → "100100011010010100011" ¥ # Get the deltas of each pair of 1s/0s # → [-1,0,1,-1,0,0,1,0,-1,1,-1,0,1,-1,1,-1,0,0,1,0] Ä # Get the absolute value of this # → [1,0,1,1,0,0,1,0,1,1,1,0,1,1,1,1,0,0,1,0] J # Join them all together # → "10110010111011110010" 1ì # And prepend a 1 # → "110110010111011110010" # (after which the result is output implicitly)  Haskell, 137 bytes import Data.Char b 0=[] b n=odd n:b(ndiv2) d x|x='1'|1<2='0' c=('1':).map d.(zipWith(/=)<*>tail).concatMap(reverse.take 7.b.(+128).ord)  Try it online! The biggest problem here is converting booleans (result of the XOR) to '0'/'1'. Python 3, 88 84 bytes l=2;s='' for c in''.join(f'{ord(c):07b}'for c in input()):s+='01'[l!=c];l=c print(s)  Try it online! I feel that the assignments should be avoidable, but couldn't think of any way to do that. Update: PHP, 90 bytes for(;$c=ord($argn[$j++]);$o.=sprintf('%07b',$c));for(;($q=$o[$i++])>'';$p=$q)echo$p!=\$q|0;


Try it online!

C# (Visual C# Interactive Compiler), 80 bytes

s=>{for(int p,c=2,i=0;i<7*s.Length;Write(p==c?0:1))(p,c)=(c,1&s[i/7]>>6-i++%7);}


Try it online!

JavaScript (V8), 73 bytes

s=>[...c=s.repeat(7)].map((_,i)=>(c=1&s.charCodeAt(i/7,p=c)>>6-i%7)!=p|0)


Try it online!