Konvertieren Sie eine "Mixed-Base" -String in ASCII


8

Bei einer Eingabe eines Strings mit Bytes, die entweder binär, oktal oder hexadezimal sein können, wird das ASCII-Äquivalent des Strings ausgegeben.

Die Eingabe erfolgt beispielsweise im folgenden Format:

501200100001147

welcher ... repräsentiert

0x50 0o120 0b01000011 0x47

Das entspricht (in ASCII)

PPCG

Binär, Oktal und Hex werden immer mit 8, 3 bzw. 2 Ziffern versehen.

Für diese Herausforderung muss nur druckbares ASCII unterstützt werden. Dies ist der Bereich 32..126inklusive. Daher ist es unmöglich, dass es Mehrdeutigkeiten gibt. Beachten Sie, dass

  • Ein String steht genau dann für binär, wenn er mit a beginnt 0und sein zweites Zeichen entweder a 0oder a ist 1. Bei allen druckbaren ASCII-Zeichen ist das High-Bit in Binärform deaktiviert (dh mit a beginnen 0), und keines von ihnen beginnt mit 00oder 01in Hex oder Oktal.

  • Beachten Sie, dass alle druckbaren ASCII-Zeichen mit 2- 7in hexadezimal und 0- 1in oktal beginnen. Daher ist es auch möglich, eindeutig zwischen hex und oktal zu unterscheiden.

Sie können davon ausgehen, dass die Hex-Eingabe entweder in Klein- oder Großbuchstaben erfolgt, je nachdem, was bequemer ist.

Regex macht den Parsing-Teil der Herausforderung halbtrivial. Ich möchte die Verwendung von Regex nicht sofort verbieten, aber wenn Sie eine Nicht-Regex-Lösung haben, die länger ist als das Gegenstück, das Regex verwendet, können Sie sie trotzdem zusammen mit der "echten" Antwort posten, da ich interessiert wäre um es auch zu sehen. :) :)

Da dies , gewinnt der kürzeste Code in Bytes.

Testfälle:

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

Antworten:


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

Kompilieren mit:

lex mixed_base.l
cc -o mixed_base lex.yy.c

Ich denke, Sie können 0[01]{7}anstelle von verwenden 0[01].{6}.
Neil

3

ES6, 86 80 Bytes

Regex-basierte Lösung:

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

Rekursive Nicht-Regex-Lösung für 95 Byte:

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

0

Python 3, 165 Bytes

Ohne 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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.