Converta uma string de "base mista" para ASCII

8

Dada a entrada de uma string com bytes que podem ser binários, octais ou hexadecimais, produz o equivalente ASCII da string.

A entrada será fornecida no seguinte formato, por exemplo:

501200100001147

que representa

0x50 0o120 0b01000011 0x47

que é equivalente (em ASCII) a

PPCG

Binário, octal e hexadecimal sempre serão fornecidos com 8, 3 e 2 dígitos, respectivamente.

Para os fins deste desafio, apenas ASCII imprimível deve ser suportado. Este é o intervalo, 32..126inclusive. Portanto, é impossível haver ambiguidade. Observe que

  • Uma cadeia de caracteres representa binário se, e somente se, começa com ae 0seu segundo caractere é a 0ou a 1. Todos os caracteres ASCII imprimíveis têm seu bit alto desativado em binário (ou seja, começam com a 0) e nenhum deles começa com 00ou 01em hexadecimal ou octal.

  • Com o binário fora do caminho, observe que todos os caracteres ASCII imprimíveis começam com 2- 7em hex e 0- 1em octal. Portanto, é possível distinguir inequivocamente entre hex e octal.

Você pode supor que a entrada hexadecimal seja fornecida como minúscula ou maiúscula, o que for mais conveniente.

O Regex torna a parte de análise do desafio semi-trivial. Não quero proibir o uso de regex diretamente, mas se você tiver uma solução que não seja regex por mais tempo que sua contraparte que usa regex, sinta-se à vontade para publicá-la juntamente com a resposta "real" de qualquer maneira, pois eu estaria interessado para ver também. :)

Como esse é o , o código mais curto em bytes será vencedor.

Casos de teste:

In                   Out
-----------------------------------
501200100001147    | PPCG
5C01101111100      | \o@
313206306400110101 | 12345
2A200530402C       | * + ,
0011111100111111   | ??
<empty string>     | <empty string>
Maçaneta da porta
fonte

Respostas:

4

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();}

Ajuntar com:

lex mixed_base.l
cc -o mixed_base lex.yy.c
Rainer P.
fonte
Eu acho que você pode usar em 0[01]{7}vez de 0[01].{6}.
Neil
3

ES6, 86 bytes de 80

Solução baseada em Regex:

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

Solução não regex recursiva 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
fonte
0

Python 3, 165 bytes

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