Convertir una cadena de "base mixta" a ASCII

8

Dada una entrada de una cadena con bytes que puede estar en binario, octal o hexadecimal, genera el equivalente ASCII de la cadena.

La entrada se proporcionará en el siguiente formato, por ejemplo:

501200100001147

que representa

0x50 0o120 0b01000011 0x47

que es equivalente (en ASCII) a

PPCG

Binario, octal y hexadecimal siempre se proporcionarán con 8, 3 y 2 dígitos respectivamente.

Para los propósitos de este desafío, solo se debe admitir ASCII imprimible. Esta es la gama 32..126inclusive. Por lo tanto, es imposible que haya ambigüedad. Tenga en cuenta que

  • Una cadena representa binario si y solo si comienza con ay 0su segundo carácter es a 0o a 1. Todos los caracteres ASCII imprimibles tienen su bit alto desactivado en binario (es decir, comienzan con a 0), y ninguno de ellos comienza con 00o 01en hexadecimal u octal.

  • Con el binario fuera del camino, tenga en cuenta que todos los caracteres ASCII imprimibles comienzan con 2- 7en hexadecimal y 0- 1en octal. Por lo tanto, es posible distinguir inequívocamente entre hex y octal también.

Puede suponer que la entrada hexadecimal se proporciona en minúsculas o mayúsculas, lo que sea más conveniente.

Regex hace que la parte de análisis del desafío sea semi-trivial. No quiero prohibir el uso de regex directamente, pero si tiene una solución que no sea regex por más tiempo que su contraparte que usa regex, no dude en publicarla junto con la respuesta "real" de todos modos, ya que estaría interesado para verlo también :)

Como se trata de , el código más corto en bytes ganará.

Casos de prueba:

In                   Out
-----------------------------------
501200100001147    | PPCG
5C01101111100      | \o@
313206306400110101 | 12345
2A200530402C       | * + ,
0011111100111111   | ??
<empty string>     | <empty string>
Pomo de la puerta
fuente

Respuestas:

4

Lex + C, 156124 bytes

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

Compilar con:

lex mixed_base.l
cc -o mixed_base lex.yy.c
Rainer P.
fuente
Creo que puedes usar en 0[01]{7}lugar de 0[01].{6}.
Neil
3

ES6, 86 80 bytes

Solución basada en expresiones regulares:

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

Solución recursiva no regex para 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
Neil
fuente
0

Python 3, 165 bytes

Sin expresiones regulares

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)
Argenis García
fuente