Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Take a string of binary characters separated by a space, and convert it to an ASCII string.

For example...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Would convert to...

Hello World

The binary string will be stored in a variable called s.

This is a code-golf challenge so the shortest solution wins.

share|improve this question
8  
+1 for making a challenge without story and other fripperies, straight to the point –  bebe Jul 25 at 18:21
4  
@bebe Fictitious fantastical fripperies form half the fun. –  qwr Jul 25 at 23:59

28 Answers 28

JavaScript (ES6) 55 56 64

Edit Accepting @bebe suggestion - thanks
Edit2 Didn't know about binary numeric literal - thanks @kapep

Explanation as requested in comments

String.replace can take 2 arguments:

  • regular expression /\d+./g : one or more digits followed by one different character - the g flag specify to search the pattern more than once
  • a function, here specified in arrow format, where the argument (x) wil be the found string (the sequence of digits eventually followed by a space) and the value of the function is what is replaced (in this case, the single character from the code).

It's worth noting that the at the end of the string the regexp matches the sequence of digits without a trailing space, in this case the dot matches the last digit. Try '123'.match(/(\d+)./) to verify.

(Still) one of the more verbose pieces of javascript ever...
(Assignment to string s not counted)

s='1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
s.replace(/\d+./g,x=>String.fromCharCode(eval('0b'+x)))
share|improve this answer
2  
s.replace(/\d+./g,x=>String.fromCharCode(parseInt(x,2))) 56 –  bebe Jul 25 at 22:35
2  
s.replace(/\d+./g,x=>String.fromCharCode(eval("0b"+x))) 55 –  kapep Jul 26 at 4:02
    
Can you please explain what the /\d+./g,x=>does? –  izlin Jul 28 at 5:38
1  
@izlin I added some explanation to the answer –  edc65 Jul 28 at 6:59

Ruby, 36 32

s.split.map{|x|x.to_i(2).chr}*""

Or 31

s.gsub(/\w+ ?/){$&.to_i(2).chr}

Optimizations thanks to Chron

share|improve this answer
1  
You could substitute .join"" for *"" to save a few characters. You could also do it with gsub instead of split+map+join, something like: s.gsub(/\w+ ?/){$&.to_i(2).chr} (31 chars). –  Chron Jul 27 at 23:41
1  
s.gsub(/\d+./){$&.to_i(2).chr} works and it's 30 chars, I have no idea why it works though. The . shouldn't match the last time but it does. –  addison Jul 30 at 4:58

Pyth, 12

smCv+"0b"dPZ

Note that s is not a legal variable in Pyth, so I used Z instead.

Explanation:

        print(
s             sum(
m                 map(lambda d:
C                     chr(
v                         eval(
+"0b"d                         "0b"+d)),
P                     split(
Z                           Z))))

Example:

=Z"<the binary string from above>"smCv+"0b"dPZ
Hello World
share|improve this answer
    
The fact it does not use whitespace in the formatting (here's looking at you Python) is a major +1 –  Pharap Jul 27 at 17:08
    
@Pharap Yeah, one way of looking at Pyth is it's Python with all of the elements that make it take more characters removed, like whitespace, parenthesis, multi-character tokens, etc. –  isaacg Jul 27 at 20:37
    
I don't know Pyth, but would it not save 4 characters to use id2 in place of v+"0b"d? In any case, this is both unreadable and cool. –  DLosc Oct 5 at 3:10
    
@DLosc I added that function to Pyth after this question was asked, in large part due to this question. It would be shorter with present day Pyth, but present day Pyth is not allowed for this challenge. –  isaacg Oct 5 at 3:38
    
I see. I wondered if it might be something like that. –  DLosc Oct 5 at 3:40

C - 57 43 38/31

38 Byte version:

for(int*x=s;putchar(strtol(x,&x,2)););

Or only 31 bytes if s is a pointer:

while(putchar(strtol(s,&s,2)));

I don't think this is exactly how for and while loop are supposed to be used... but it works.

share|improve this answer

Bash+common linux utils, 25 bytes

dc<<<2i$s[Pz0\<m]dsmx|rev

dc explanation

  • push 2 to the stack; pop and use as input radix
  • push input string to stack (all values at once)
  • Define recursive macro m to:
    • pop, then print value as ASCII
    • push stack depth to stack
    • push 0 to stack
    • pop top 2 stack values; compare and call m macro if stack non-empty
  • duplicate top of stack (macro definition)
  • pop and save macro to m register
  • pop and execute macro

Because we push the whole binary string to the stack first, when we pop each value, we end up with the string reversed. So we use the rev utility to correct that.

Example usage:

$ s="1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
$ dc<<<2i$s[Pz0\<m]dsmx|rev
Hello World
$ 
share|improve this answer

x86 machine code on DOS - 22 bytes

00000000  30 d2 b4 08 cd 21 2c 30  72 06 d0 e2 08 c2 eb f2  |0....!,0r.......|
00000010  b4 02 cd 21 eb ea                                 |...!..|

Since there are no real string variables in machine code (and in particular, no variables named "s") I settled for stdin as input.

NASM input:

    org 100h

section .text

start:
    xor dl,dl
loop:
    mov ah,8
    int 21h
    sub al,'0'
    jb print
    shl dl,1
    or dl,al
    jmp loop
print:
    mov ah,2
    int 21h
    jmp start
share|improve this answer

Mathematica, 52 bytes

Ah, Mathematica's lovely function names

f=FromCharacterCode[#~FromDigits~2&/@StringSplit@#]&
share|improve this answer

Perl 33 32

Edit: Updated solution, 32.

say$s=~s/\d+ ?/chr oct"0b$&"/rge

Previous solution (33):

$_=$s;say map{chr oct"0b$_"}split

or

say map{chr oct"0b$_"}split/ /,$s

Test:

perl -E '$s="1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100";$_=$s;say map{chr oct"0b$_"}split'
share|improve this answer

PowerShell, 49

-join(-split$s|%{[char][convert]::toint32($_,2)})

EDIT: Didn't see the other PowerShell answer. But there is essentially only one way of solving this.

share|improve this answer

Golfscript - 21

' '/{1/{~}%2base}%''+

You can test it here.

share|improve this answer

Python shell  44  40 chars

''.join(chr(int(x,2))for x in s.split())

Thanks for the help Griffin.

share|improve this answer
    
''.join(chr(int(x,2))for x in s.split()) –  Griffin Jul 25 at 17:55

Run Length Encoded Brainfuck, 49 bytes

Since there are no variables in Brainfuck, I just used standard input and output instead.

The code 32+ should be interpreted as 32 +s by the interpreter. Just replace them manually if your interpreter doesn't support RLE.

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

Expanded (non-RLE) version: (91 bytes)

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

The code assumes that EOF is encoded as 0.

Explanation

The following layout is used:

+---+---+------+
| x | a | flag |
+---+---+------+

Where x is the ASCII byte to be printed, a is the a character from standard input and flag is 1 if a was a space.

>,            Read a character a into the second cell
[             While not EOF: 
  32-           Decrease a by 32 (a -= ' ')
  >+<           Set the flag to 1 
  [             If a was not a space:
    16-           Decrease by 16 more ('0' == 32+16)
    <[>++<-]      a += 2*x
    >[<+>-]       Move it back (x = a)
    >-<           Reset the flag, it was not a space.
  ]>
  [             If a was a space (flag == 1):
    <<.[-]        Print and reset x
    >>-           Reset the flag
  ]
  <,            Read the next caracter a
]
<.            Print the last character x
share|improve this answer
1  
+1 Because everything should have a brainfuck implementation. –  Pharap Jul 27 at 17:09

GolfScript 23

' '/{[{49=}/]2base}%''+

Online test here.

share|improve this answer

C - 63

since C has no base 2 converter in standard library: test here
edit: there is, i'm just too stupid to know about it

r;f(char*s){for(;*s;(*s|32)-32||(putchar(r),r=0))r=2*r|*s++&1;}
share|improve this answer

Powershell (52 49)

-join(-split$s|%{[char][convert]::ToInt16($_,2)})

Simple loop over binary string in $s. Having to include the [convert] kills my score though.

EDIT: There really is only one way of pulling this off in Powershell, wowie. Joey and I both got pretty much the same answer working independently!

Input:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Output:

Hello World
share|improve this answer
1  
You can use the unary split operator, saving three characters (at which point our answers are identical ... big surprise ;-)). –  Joey Jul 25 at 22:06
    
@Joey Ohh, good point! Can't believe I missed that. You get the +1 from me for catching that, thanks! –  fuandon Jul 26 at 2:53

APL (15)

⎕UCS{2⊥⍎¨⍕⍵}¨⍎s

Test:

      s←'1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
      ⎕UCS{2⊥⍎¨⍕⍵}¨⍎s
Hello World

Explanation:

  • ⍎s: evaluate s, turning it into an array of integers. Arrays are written as numbers separated by spaces, so this splits s.
  • {...: for each element:
    • ⍕⍵: turn the number back into a string
    • ⍎¨: evaluate each individual digit, giving a bitstring
    • 2⊥: base-2 decode, giving the numbers
  • ⎕UCS: get the character for each number
share|improve this answer
    
Unless otherwise specified you should count bytes instead of characters: codegolf.stackexchange.com/tags/code-golf/info :) –  Averroes Jul 28 at 9:36
1  
@Averroes: the APL charset fits in a byte with room to spare: frankenstein.d-n-s.org.uk/~marinus/aplcharset.png –  marinus Jul 31 at 12:04
    
Ah, I didn't know it. My bad. Sorry! –  Averroes Jul 31 at 12:10

Java 8 : 60 bytes

Using lambdas in Java 8 (75 bytes):

Arrays.stream(s.split(" ")).reduce("",(a,b)->a+(char)Byte.parseByte(b,2));

And if you allow static imports (which some here used) it is (61 bytes):

stream(s.split(" ")).reduce("",(a,b)->a+(char)parseInt(b,2))

A tiny bit shorter version using for loop (60 bytes):

for(String n:s.split(" ")){out.print((char)parseInt(n,2));}
share|improve this answer
2  
What, they actually made a replacement for the monstrosity known as anonymous class? Awesome. –  Sieg Jul 28 at 8:53
    
@Sieg yes Java has lambdas/closures now as well, but it is mostly synthetic sugar on top of anonymous classes... (obviously) –  Roy van Rijn Jul 28 at 12:39

Bacchus, 25 bytes

S,' 'j:A=(Ö,2,10b:c),A¨

Explanation:

S,' 'j split the String S by the empty space and converts it to a block (some sort of array).

:A= get the previous Block and assing it to A variable.

(),A¨ for Each element in A

Ö,2,10b Read the current element (represent by Ö) in base 2 and transform it to base 10.

:c get the previous value and print as char

share|improve this answer

Clojure 63 (or 57)

The all-Clojure impl:

(apply str(map #(char(read-string(str"2r"%)))(re-seq #"\d+"s)))

With Java interop:

(apply str(map #(char(Long/parseLong % 2))(.split s" ")))

REPL session:

golf> (def s "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100")
#'golf/s
golf> (apply str(map #(char(read-string(str"2r"%)))(re-seq #"\d+"s)))
"Hello World"
golf> (apply str(map #(char(Long/parseLong % 2))(.split s" ")))
"Hello World"
share|improve this answer

NodeJS62

Buffer(s.split(' ').map(function(a){return parseInt(a,2)}))+''

PHP75

array_reduce(explode(' ', $b),function($a,$b){return $a.chr(bindec($b));});
share|improve this answer
    
how do you run nodejs with es6 compatibility? the latest one still does not support lambda functions for me –  bebe Jul 26 at 14:35
    
@bebe Arrow functions are implemented in v8 but they aren't integrated with node yet. I'll edit my post. –  c.P.u1 Jul 26 at 15:05

J (23)

u:;(#.@:("."0))&.>cut s

Test:

   s=:'1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
   u:;(#.@:("."0))&.>cut s
Hello World

Explanation:

                  cut s    NB. split S on spaces
   (          )&.>         NB. for each element
        ("."0)             NB. evaluate each character
      @:                   NB. and
    #.                     NB. convert bitstring to number
  ;                        NB. unbox each number
u:                         NB. convert to ASCII
share|improve this answer

JavaScript 111

This does the number conversion without parseInt or eval. Reading the string backwards and counting bits it set's bit x if it's a one. When a space is found a the number is converted to a char and a new 0 number is started for setting bits.

x=n=0,w='',s=' '+s
for(i=s.length;i--;){m=s[i]
if(m==1)n|=1<<x
x++
if(m==' ')w=String.fromCharCode(n)+w,n=x=0
}
share|improve this answer
1  
+1 for doing it the old-fashioned way--inspired me to write a QBasic version, too. –  DLosc Oct 5 at 3:29

PHP (61)

<?=join(array_map('chr',array_map('bindec',explode(' ',$s))))
share|improve this answer

Groovy 64

{it.split(" ").collect{Integer.parseInt(it,2) as char}.join("")}
share|improve this answer

QBasic, 103

s$=s$+" ":FOR i=1 TO LEN(s$):c$=MID$(s$,i,1):IF c$=" "THEN n=0:r$=r$+CHR$(n)ELSE n=n*2+VAL(c$)
NEXT:?r$

What? We have no fancy binary-to-decimal functions here. Do it yourself!

I'm counting the newline (which I think is necessary to get the if-then-else without an END IF) as one byte, per this meta post. I don't know whether QB64 on Windows would accept a code file that way or not. Probably doesn't much matter.

share|improve this answer

Haskell -- 48 (+13 imports (?))

Here's my first golf attempt in Haskell.

map(chr.foldl1((+).(*2)).map digitToInt)$words s

You need to import Data.Char

usage (in ghci):

Prelude> :m +Data.Char
Prelude Data.Char> let s = "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
Prelude Data.Char> map(chr.foldl1((+).(*2)).map digitToInt)$words s
"Hello World"

Explanation:

map(chr.foldl1((+).(*2)).map digitToInt)$words s
                                        $words s -- split s on spaces into a list
                         map digitToInt          -- convert each digit in input string to int
              ((+).(*2))                         -- a function that multiplies its first 
-- argument by 2, then adds the second argument
        foldl1((+).(*2)).map digitToInt          -- fold the above over the list of ints: 
-- in other words this is a function that reads strings as binary and gives the value as int
   (chr.foldl1((+).(*2)).map digitToInt)         -- cast to character
map(chr.foldl1((+).(*2)).map digitToInt)$words s -- map our function over the list of words
share|improve this answer
    
Hopefully I've followed scoring conventions correctly regarding imports. Feel free to edit in a correction if I haven't. I treated the ":m +Data.Char" needed to import in ghci as 13. –  ballesta25 Jul 26 at 2:30

CJam, 11 bytes

NS/{:~2bc}/

s isn't a legal variable name in CJam, so I chose N instead.

Try it online.

Example run

$ cjam <(echo '
> "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
> :N;
> NS/{:~2bc}/
> '); echo
Hello World

How it works

NS/            " Split N at spaces.                            ";
   {     }/    " For each chunk:                               ";
    :~         "   Evaluate each character ('0' ↦ 0, '1' ↦ 1). ";
      2b       "   Convert from base 2 array to integer.       ";
        c      "   Cast to character.                          ";
share|improve this answer

Lua, 59 bytes

for k in s:gmatch'%d+'do io.write(s.char(tonumber(k,2)))end
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.