Konvertieren Sie eine Folge von Binärzeichen in ASCII-Entsprechungen


27

Nehmen Sie eine durch ein Leerzeichen getrennte Folge von Binärzeichen und konvertieren Sie sie in eine ASCII-Zeichenfolge.

Beispielsweise...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Würde konvertieren zu ...

Hello World

Die Binärzeichenfolge wird in einer Variablen namens gespeichert s.

Dies ist eine Code-Golf-Herausforderung, bei der die kürzeste Lösung gewinnt.


15
+1 für eine Herausforderung , ohne Geschichte und anderen Firlefanz zu machen, direkt auf den Punkt
bebe

9
@bebe Fiktive, fantastische Fripperies machen den halben Spaß.
Qwr

Hallo. Stellen wir uns vor, Ihre Technologie ist so fortschrittlich, dass sie ASCII nicht unterstützt. Würde es erlaubt sein, in die native Zeichenkodierung zu konvertieren, oder müsste es ASCII in die native Zeichenkodierung konvertieren? Ich denke ZX81hier nach.
Shaun Bebbers

Antworten:


10

Ruby, 36 32

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

Oder 31

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

Optimierungen dank Chron


1
Sie könnten Ersatz .join""für *""ein paar Zeichen zu speichern. Du könntest es auch mit gsub machen, anstatt split + map + join, so etwas wie: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 Zeichen).
Paul Prestidge

2
s.gsub(/\d+./){$&.to_i(2).chr}funktioniert und es ist 30 Zeichen, ich habe keine Ahnung, warum es funktioniert. Das .sollte nicht zum letzten Mal passen, aber das tut es.
Addison

10

JavaScript (ES6) 49 55 56 64

s.replace(/\d+./g,x=>String.fromCharCode('0b'+x))

Bearbeiten Akzeptiere @bebe Vorschlag - danke
Bearbeiten2 Wusste nichts über binäres numerisches Literal - danke @kapep
Bearbeiten3 Wow 6, nicht 4 Bytes gespeichert dank @ETHproductions

Erklärung wie in den Kommentaren angefordert

String.replace kann 2 Argumente annehmen:

  • regulärer Ausdruck /\d+./g: eine oder mehrere Ziffern, gefolgt von einem anderen Zeichen - das g-Flag gibt an, dass das Muster mehrmals durchsucht werden soll
  • Eine hier im Pfeilformat angegebene Funktion, bei der das Argument (x) die gefundene Zeichenfolge ist (die Ziffernfolge, auf die schließlich ein Leerzeichen folgt) und der Wert der Funktion ersetzt wird (in diesem Fall das einzelne Zeichen aus der Code).

Es ist erwähnenswert, dass der reguläre Ausdruck am Ende der Zeichenfolge mit der Ziffernfolge ohne Leerzeichen übereinstimmt. In diesem Fall stimmt der Punkt mit der letzten Ziffer überein. Versuchen Sie es mit '123'.match (/ (\ d +) ./).

(Immer noch) eines der ausführlicheren Javascript-Elemente aller Zeiten ...
(Zuweisung zu Zeichenfolge wird nicht gezählt)

var s='1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
var x=
s.replace(/\d+./g,x=>String.fromCharCode('0b'+x))

console.log(x)


2
s.replace(/\d+./g,x=>String.fromCharCode(parseInt(x,2)))56
Bebe

2
s.replace(/\d+./g,x=>String.fromCharCode(eval("0b"+x)))55
kapex

Kannst du bitte erklären, was das /\d+./g,x=>macht?
Izlin

1
@izlin Ich habe der Antwort eine Erklärung hinzugefügt
edc65

Ich weiß , das ist eine alte Antwort, aber man kann sich ändern eval('0b'+x)zu '0b'+x-04 Byte zu speichern.
ETHproductions

8

Bash + gemeinsame Linux-Utils, 25 Bytes

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

dc erklärung

  • Drücke 2 auf den Stapel. Pop und als Eingabe-Radix verwenden
  • Eingabezeichenfolge zum Stapeln verschieben (alle Werte gleichzeitig)
  • Definieren Sie ein rekursives Makro, mum:
    • pop, dann Wert als ASCII ausgeben
    • Stapeltiefe zum Stapeln drücken
    • 0 drücken, um zu stapeln
    • Pop-Top-2-Stack-Werte; vergleiche und rufe das mMakro auf, wenn der Stack nicht leer ist
  • Stapelanfang duplizieren (Makrodefinition)
  • Pop und Makro speichern, um sich zu mregistrieren
  • Pop und Makro ausführen

Da wir die gesamte Binärzeichenfolge zuerst in den Stapel verschieben, wird die Zeichenfolge beim Aufrufen der einzelnen Werte umgekehrt. Also verwenden wir das revDienstprogramm, um das zu korrigieren.

Anwendungsbeispiel:

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

7

PowerShell, 49

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

BEARBEITEN: Die andere PowerShell-Antwort wurde nicht angezeigt. Aber es gibt im Wesentlichen nur einen Weg, dies zu lösen.


7

C - 57 43 38/31

38 Byte Version:

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

Oder nur 31 Bytes, wenn s ein Zeiger ist:

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

Ich denke nicht, dass dies genau die Art und Weise ist, wie eine for and while-Schleife verwendet werden soll ... aber es funktioniert.


6

Pyth , 12

smCv+"0b"dPZ

Beachten Sie, dass s in Pyth keine legale Variable ist, also habe ich stattdessen Z verwendet.

Erläuterung:

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

Beispiel:

=Z"<the binary string from above>"smCv+"0b"dPZ
Hello World

Die Tatsache, dass bei der Formatierung kein Leerzeichen verwendet wird (hier sehen Sie Python), ist eine wichtige +1
Pharap

@Pharap Ja, eine Sichtweise auf Pyth ist Python mit all den Elementen, die dazu führen, dass mehr Zeichen entfernt werden, wie Leerzeichen, Klammern, Token mit mehreren Zeichen usw.
isaacg

Ich kenne Pyth nicht, aber würde es nicht 4 Zeichen speichern, um sie id2anstelle von zu verwenden v+"0b"d? In jedem Fall ist dies sowohl unlesbar als auch cool.
DLosc

@ DLosc Ich habe diese Funktion zu Pyth hinzugefügt, nachdem diese Frage zum großen Teil aufgrund dieser Frage gestellt wurde. Es wäre kürzer mit dem heutigen Pyth, aber das heutige Pyth ist für diese Herausforderung nicht erlaubt.
isaacg

Aha. Ich fragte mich, ob es so etwas sein könnte.
DLosc

6

x86-Maschinencode unter DOS - 22 Byte

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                                 |...!..|

Da der Maschinencode keine echten Zeichenfolgenvariablen enthält (und insbesondere keine Variablen mit dem Namen "s "), habe ich mich für stdin als Eingabe entschieden.

NASM-Eingabe:

    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

6

Powershell ( 52 49)

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

Einfache Schleife über binären String in $ s. Das Einschließen von [convert] tötet meine Punktzahl.

EDIT: Es gibt wirklich nur einen Weg, dies in Powershell durchzuziehen, wowie. Joey und ich haben fast die gleiche Antwort bekommen, wenn wir unabhängig voneinander arbeiten!

Eingang:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Ausgabe:

Hello World

1
Sie können den unären Split-Operator verwenden und drei Zeichen speichern (an diesem Punkt sind unsere Antworten identisch ... große Überraschung ;-)).
Joey

@ Joey Ohh, guter Punkt! Ich kann nicht glauben, dass ich das verpasst habe. Du bekommst die +1 von mir dafür, dass du das erwischt hast, danke!
Fuandon

5

Mathematica, 52 Bytes

Ah, Mathematics schöne Funktionsnamen

f=FromCharacterCode[#~FromDigits~2&/@StringSplit@#]&

5

Perl 33 32

Bearbeiten: Aktualisierte Lösung, 32.

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

Vorherige Lösung (33):

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

oder

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

Prüfung:

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

5

J (23)

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

Prüfung:

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

Erläuterung:

                  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


4

Python-Shell  44  40 Zeichen

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

Danke für die Hilfe Griffin .


'' .join (chr (int (x, 2)) für x in s.split ())
Griffin

4

APL (15)

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

Prüfung:

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

Erläuterung:

  • ⍎s: auswerten s, in ein Array von ganzen Zahlen verwandeln. Arrays werden als Zahlen geschrieben, die durch Leerzeichen getrennt sind s.
  • {... : für jedes Element:
    • ⍕⍵: verwandle die Zahl wieder in eine Zeichenfolge
    • ⍎¨: werte jede einzelne Ziffer aus und gib einen Bitstring
    • 2⊥: Base-2-Dekodierung unter Angabe der Zahlen
  • ⎕UCS: Ermittelt das Zeichen für jede Zahl

Sofern nicht anders angegeben, sollten Sie Bytes anstelle von Zeichen zählen: codegolf.stackexchange.com/tags/code-golf/info :)
Averroes

1
@Averroes: Der APL-Zeichensatz passt in ein Byte mit freiem Speicherplatz: frankenstein.dns.org.uk/~marinus/aplcharset.png
Marinus

Ah, ich wusste es nicht. Mein Fehler. Es tut uns leid!
Averroes

4

PHP (61)

<?=join(array_map('chr',array_map('bindec',explode(' ',$s))))

foreach(str_split($s,8)as$v)echo chr(bindec($v));
Jörg Hülsermann

@ JörgHülsermann die Kodierung kann führende Nullen überspringen, str_split($s,8)funktioniert also nicht. foreach(explode(' ',$s)as$v)echo chr(bindec($v));wäre gültig, aber ich habe nicht vor, eine meiner ersten PPGC-Antworten zu bearbeiten, die offensichtlich sowieso nicht wirklich golfen ist. Trotzdem danke!
Christoph

4

Bacchus , 25 Bytes

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

Erläuterung:

S,' 'j Teilen Sie den String S durch den leeren Raum und konvertieren Sie ihn in einen Block (eine Art Array).

:A= Holen Sie sich den vorherigen Block und weisen Sie ihn der Variablen A zu.

(),A¨ für jedes Element in A

Ö,2,10bLesen Sie das aktuelle Element (repräsentiert durch Ö) in Basis 2 und transformieren Sie es in Basis 10.

:c Holen Sie sich den vorherigen Wert und drucken Sie ihn als Zeichen



3

C - 63

da c keinen base 2 konverter in der standard bibliothek hat: test hier
edit: da bin ich einfach zu doof um es zu wissen

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

3

Lauflängencodiertes Brainfuck, 49 Bytes

Da es in Brainfuck keine Variablen gibt, habe ich stattdessen nur die Standardeingabe und -ausgabe verwendet.

Der Code 32+sollte vom Interpreter als 32 +s interpretiert werden. Ersetzen Sie sie einfach manuell, wenn Ihr Dolmetscher RLE nicht unterstützt.

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

Erweiterte (Nicht-RLE) Version: (91 Bytes)

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

Der Code setzt voraus, dass EOF als 0 codiert ist.

Erläuterung

Das folgende Layout wird verwendet:

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

Wo xsoll das ASCII-Byte gedruckt werden, aist das Zeichen aus der Standardeingabe und flagist 1, wenn awar ein Leerzeichen.

>,            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

1
+1 Weil alles eine Brainfuck-Implementierung haben sollte.
Pharap

Ist "Run Length Encoded Brainfuck" eine eigene Sprache? Ich kann keinen Dolmetscher finden.
mbomb007

3

Java 8: 60 Bytes

Verwenden von Lambdas in Java 8 (75 Byte):

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

Und wenn Sie statische Importe zulassen (die einige hier verwendet haben), sind es (61 Bytes):

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

Eine etwas kürzere Version mit for-Schleife (60 Bytes):

for(String n:s.split(" ")){out.print((char)parseInt(n,2));}

2
Was, sie machten tatsächlich einen Ersatz für die als anonyme Klasse bekannte Monstrosität? Genial.
Siehe auch

@Sieg ja Java hat jetzt auch Lambdas / Closures, aber es ist meistens synthetischer Zucker, zusätzlich zu anonymen Klassen ... (offensichtlich)
Roy van Rijn

3

Clojure 63 (oder 57)

Das All-Clojure-Werkzeug:

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

Mit Java Interop:

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

REPL-Sitzung:

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"

3

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$

Was? Wir haben hier keine ausgefallenen Binär-zu-Dezimal-Funktionen. Mach es selbst!

Ich zähle die neue Zeile (die ich für notwendig halte, um das Wenn-Dann-Sonst ohne zu erhalten END IF) als ein Byte pro Metapost . Ich weiß nicht, ob QB64 unter Windows eine Codedatei auf diese Weise akzeptieren würde oder nicht. Vermutlich spielt nicht viel eine Rolle.


2

NodeJS - 62

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

PHP - 75

array_reduce(explode(' ', $b),function($a,$b){return $a.chr(bindec($b));});

Wie führt man NodeJS mit ES6-Kompatibilität aus? Die neueste
Version

@bebe Arrow-Funktionen sind in Version 8 implementiert, aber noch nicht in Node integriert. Ich werde meinen Beitrag bearbeiten.
cPu1

@ cPu1 sie arbeiten für mich
Benutzername.ak

2

JavaScript 111

Dies führt die Zahlenkonvertierung ohne parseInt oder eval durch. Lesen Sie die Zeichenfolge rückwärts und zählen Sie die Bits, die das Bit x gesetzt hat, wenn es eine Eins ist. Wenn ein Leerzeichen gefunden wird, wird die Zahl in ein Zeichen umgewandelt und eine neue 0-Zahl zum Setzen von Bits gestartet.

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
}

1
+1 für die altmodische Arbeitsweise - inspirierte mich, auch eine QBasic-Version zu schreiben.
DLosc

Ungültig, muss eine Funktion oder ein vollständiges Programm sein (eines, das Eingaben akzeptiert)
Nur ASCII

2

Groovy 64

{it.split(" ").collect{Integer.parseInt(it,2) as char}.join("")}

2

CJam, 11 Bytes

NS/{:~2bc}/

s ist in CJam kein zulässiger Variablenname, daher habe ich stattdessen N gewählt.

Probieren Sie es online aus.

Beispiellauf

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

Wie es funktioniert

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.                          ";

2

Haskell - 48 (+13 Importe (?))

Hier ist mein erster Golfversuch in Haskell.

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

Sie müssen Data.Char importieren

Verwendung (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"

Erläuterung:

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

Hoffentlich habe ich die Bewertungskonventionen für Importe korrekt befolgt. Fühlen Sie sich frei, in einer Korrektur zu bearbeiten, wenn ich nicht habe. Ich habe das ": m + Data.Char", das in ghci importiert werden muss, als 13.
ballesta25

1

GNU Sed, 19 Bytes

Inspiriert von einer exzellenten @ Digital Trauma Antwort.

Golf gespielt

s/\w*/dc -e2i&P;/eg

Prüfung

echo 1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100|\
sed 's/\w*/dc -e2i&P;/eg'

Hello World

1

Pyth, 7 Bytes (nicht konkurrierend)

smCid2c

Übernimmt die Eingabe als String.

Versuch es!


Als nicht konkurrierend markiert, da die Sprache neuer ist als die Herausforderung.
mbomb007

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.