Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given an input of a string with bytes that may be in either binary, octal, or hex, output the string's ASCII equivalent.

Input will be provided in the following format, for example:

501200100001147

which represents

0x50 0o120 0b01000011 0x47

which is equivalent (in ASCII) to

PPCG

Binary, octal, and hex will always be provided with 8, 3, and 2 digits respectively.

For the purposes of this challenge, only printable ASCII must be supported. This is the range 32..126 inclusive. Therefore, it is impossible for there to be ambiguity. Note that

  • A string represents binary if and only if it starts with a 0 and its second character is either a 0 or a 1. All printable ASCII characters have their high bit off in binary (i.e. start with a 0), and none of them start with 00 or 01 in either hex or octal.

  • With binary out of the way, note that all printable ASCII characters start with 2-7 in hex and 0-1 in octal. Therefore, it is possible to unambiguously distinguish between hex and octal as well.

You may assume that hex input is provided as either lowercase or uppercase, whichever is more convenient.

Regex makes the parsing portion of the challenge semi-trivial. I don't want to ban the use of regex outright, but if you have a non-regex solution longer than its regex-using counterpart, feel free to post it along with the "real" answer anyway, since I'd be interested to see it as well. :)

Since this is , the shortest code in bytes will win.

Test cases:

In                   Out
-----------------------------------
501200100001147    | PPCG
5C01101111100      | \o@
313206306400110101 | 12345
2A200530402C       | * + ,
0011111100111111   | ??
<empty string>     | <empty string>
share|improve this question

Lex + C, 156 124 bytes

%{
p(b){putchar(strtol(yytext,0,b));}
%}
%option noyywrap
%%
0[01]{7} {p(2);}
[01].. {p(8);}
.. {p(16);}
%%
main(){yylex();}

Compile with:

lex mixed_base.l
cc -o mixed_base lex.yy.c
share|improve this answer
    
I think you can use 0[01]{7} instead of 0[01].{6}. – Neil Feb 16 at 21:48
    
@Neil Indeed. Thanks. – Rainer P. Feb 16 at 21:57

ES6, 86 80 bytes

Regex-based solution:

s=>s.replace(/0[01]{7}|[01]?../g,n=>String.fromCharCode(0+'bkxo'[n.length&3]+n))

Recursive non-regex solution for 95 bytes:

f=(s,r='')=>s?f(s.slice(l=s<'02'?8:s<'2'|2),r+String.fromCharCode(0+'bkxo'[l&3]+s.slice(0,l))):r
share|improve this answer

Python 3, 165 bytes

Without Regex

x=input();i=0;s=""
while i<len(x):
 a=x[i:i+2];c=int(a[0])
 if a in["00","01"]:y=8;b=2
 elif 1<c<8:y=2;b=16
 elif c<2:y=3;b=8
 s+=chr(int(x[i:i+y],b));i+=y
print(s)
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.