Konwertuj ciąg znaków binarnych na odpowiedniki ASCII


27

Weź ciąg znaków binarnych oddzielonych spacją i przekonwertuj go na ciąg ASCII.

Na przykład...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Konwertuje się na ...

Hello World

Ciąg binarny zostanie zapisany w zmiennej o nazwie s.

To wyzwanie dla golfa, więc wygrywa najkrótsze rozwiązanie.


15
+1 za wykonanie wyzwania bez fabuły i innych drobiazgów, od razu do
— rzeczy

9
@bebe Fikcyjne fantastyczne fripperie stanowią połowę zabawy.
— qwr

Witaj. Wyobraźmy sobie, że twoja technologia jest tak zaawansowana, że ​​nie obsługuje ASCII. Czy wolno byłoby przekonwertować na kodowanie znaków natywnych, czy też musiałby przekonwertować ASCII na kodowanie znaków natywnych? Myślę ZX81tutaj.
— Shaun Bebbers

Odpowiedzi:


10

Ruby, 36 32

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

Lub 31

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

Optymalizacje dzięki Chronowi


1
Można podstawić .join""do *""zaoszczędzić kilka znaków. Możesz to również zrobić za pomocą gsub zamiast split + map + join, coś w stylu: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 znaków).
— Paul Prestidge

2
s.gsub(/\d+./){$&.to_i(2).chr}działa i jest 30 znaków, ale nie mam pojęcia, dlaczego to działa. Nie .powinno pasować do ostatniego razu, ale tak jest.
— addison

10

JavaScript (ES6) 49 55 56 64

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

Edytuj Akceptowanie sugestii @bebe - dzięki
Edit2 Nie wiedziałem o binarnym dosłownym - dzięki @kapep
Edit3 Wow 6 nie 4 bajty zapisane thx @ETHproductions

Wyjaśnienie zgodnie z żądaniem w komentarzach

String.replace może przyjąć 2 argumenty:

  • wyrażenie regularne /\d+./g: jedna lub więcej cyfr, po których następuje jeden inny znak - flaga g określa, że ​​wzór ma być przeszukiwany więcej niż jeden raz
  • funkcja, określona tutaj w formacie strzałki, w której argument (x) będzie znalezionym łańcuchem (sekwencja cyfr, po której następuje spacja), a wartość funkcji jest zastępowana (w tym przypadku pojedynczy znak z kod).

Warto zauważyć, że na końcu łańcucha wyrażenie regularne pasuje do sekwencji cyfr bez spacji końcowej, w tym przypadku kropka odpowiada ostatniej cyfrze. Spróbuj „123”. Dopasuj (/ (\ d +) ./), aby zweryfikować.

(Nadal) jeden z bardziej pełnych fragmentów javascript kiedykolwiek ...
(Przypisanie ciągów nie jest liczone)

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

Czy możesz wyjaśnić, co to /\d+./g,x=>robi?
— izlin

1
@izlin Do odpowiedzi dodałem wyjaśnienie
— edc65,

Wiem, że to stary odpowiedź, ale można zmienić eval('0b'+x), aby '0b'+x-0zapisać 4 bajty.
— ETHprodukcje

8

Bash + wspólne narzędzia linuksowe, 25 bajtów

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

wyjaśnienie DC

  • pchnij 2 na stos; pop i użyj jako podstawa wejściowa
  • push ciąg wejściowy do stosu (wszystkie wartości jednocześnie)
  • Zdefiniuj makro rekurencyjne, maby:
    • pop, a następnie wydrukuj wartość jako ASCII
    • Wciśnij głębokość stosu do stosu
    • push 0, aby kumulować
    • wyskakuj z górnych 2 wartości stosu; porównaj i wywołaj mmakro, jeśli stos nie jest pusty
  • zduplikowany początek stosu (definicja makra)
  • pop i zapisz makro, aby się mzarejestrować
  • pop i uruchom makro

Ponieważ najpierw wypychamy cały ciąg binarny do stosu, kiedy popujemy każdą wartość, kończymy na odwróconym ciągu. Więc używamy tego revnarzędzia, aby to poprawić.

Przykładowe użycie:

$ 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)})

EDYCJA: Nie widziałem innej odpowiedzi PowerShell. Ale jest zasadniczo tylko jeden sposób na rozwiązanie tego.


7

C - 57 43 38/31

38 bajtów wersja:

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

Lub tylko 31 bajtów, jeśli s jest wskaźnikiem:

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

Nie sądzę, że tak właśnie należy używać pętli for i while ... ale to działa.


6

Pyth , 12

smCv+"0b"dPZ

Zauważ, że s nie jest dopuszczalną zmienną w Pyth, więc zamiast tego użyłem Z.

Wyjaśnienie:

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

Przykład:

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

Fakt, że nie używa białych znaków w formatowaniu (tutaj patrzy na ciebie Python), jest głównym +1
— Pharap

@Pharap Tak, jednym ze sposobów patrzenia na Pyth jest Python ze wszystkimi elementami, które powodują, że usuwa więcej znaków, takich jak spacje, nawiasy, tokeny
— wieloznakowe

Nie znam Pytha, ale czy nie zachowałoby 4 znaków id2zamiast v+"0b"d? W każdym razie jest to zarówno nieczytelne, jak i fajne.
— DLosc

@DLosc Dodałem tę funkcję do Pytha po zadaniu tego pytania, w dużej mierze z powodu tego pytania. Byłoby krócej w przypadku dzisiejszego Pytha, ale dzisiejsze Pyth nie jest dozwolone dla tego wyzwania.
— isaacg

Widzę. Zastanawiałem się, czy to może być coś takiego.
— DLosc

6

Kod maszynowy x86 w systemie DOS - 22 bajty

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

Ponieważ w kodzie maszynowym nie ma żadnych rzeczywistych zmiennych łańcuchowych (a w szczególności żadnych zmiennych o nazwie „ s”), zdecydowałem się na wejście standardowe.

Wejście NASM:

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

Prosta pętla nad ciągiem binarnym w $ s. Jednak włączenie [konwersji] zabija mój wynik.

EDYCJA: Naprawdę jest tylko jeden sposób, aby to zrobić w PowerShell, wowie. Joey i ja otrzymaliśmy prawie taką samą odpowiedź działającą niezależnie!

Wkład:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Wydajność:

Hello World

1
Możesz użyć jednoargumentowego operatora podziału, oszczędzając trzy znaki (w tym momencie nasze odpowiedzi są identyczne ... wielka niespodzianka ;-)).
— Joey,

@Joey Ohh, dobra uwaga! Nie mogę uwierzyć, że to przegapiłem. Dostajesz ode mnie +1 za złapanie tego, dzięki!
— fuandon

5

Mathematica, 52 bajty

Ach, piękne nazwy funkcji Mathematiki

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

5

Perl 33 32

Edycja: zaktualizowane rozwiązanie, 32.

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

Poprzednie rozwiązanie (33):

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

lub

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

Test:

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

Test:

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

Wyjaśnienie:

                  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

APL (15)

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

Test:

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

Wyjaśnienie:

  • ⍎s: ocena s, zamieniając go w tablicę liczb całkowitych. Tablice są zapisywane jako liczby oddzielone spacjami, więc dzieli się s.
  • {... }¨: dla każdego elementu:
    • ⍕⍵: zamień liczbę z powrotem na ciąg znaków
    • ⍎¨: oceniaj każdą pojedynczą cyfrę, podając ciąg bitów
    • 2⊥: dekodowanie base-2, podając liczby
  • ⎕UCS: uzyskaj znak dla każdej liczby

O ile nie określono inaczej, zamiast znaków należy liczyć bajty: codegolf.stackexchange.com/tags/code-golf/info :)
— Averroes

1
@Averroes: zestaw znaków APL mieści się w bajcie z miejscem do oszczędzania: frankenstein.dns.org.uk/~marinus/aplcharset.png
— marinus

Ach, nie wiedziałem o tym. Mój błąd. Przepraszam!
— 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 kodowanie może pomijać zera na początku, dlatego str_split($s,8)nie będzie działać. foreach(explode(' ',$s)as$v)echo chr(bindec($v));byłoby ważne, ale nie planuję edytować jednej z moich pierwszych odpowiedzi PPGC, która oczywiście nie jest tak naprawdę golfa. Mimo wszystko dziekuję!
— Christoph

4

Bachus , 25 bajtów

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

Wyjaśnienie:

S,' 'j podziel String S przez pustą spację i przekształci go w blok (pewnego rodzaju tablicę).

:A= pobierz poprzedni Blok i przypisz go do zmiennej A.

(),A¨ dla każdego elementu w A

Ö,2,10bPrzeczytaj bieżący element (reprezentuj przez Ö) w bazie 2 i przekształć go w bazę 10.

:c pobierz poprzednią wartość i wydrukuj jako char



3

C - 63

ponieważ C nie ma konwertera base 2 w standardowej bibliotece: przetestuj tutaj
edytuj: jest, jestem po prostu zbyt głupi, żeby o tym wiedzieć

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

3

Brainfuck z kodowaniem długości przebiegu, 49 bajtów

Ponieważ w Brainfuck nie ma żadnych zmiennych, po prostu użyłem standardowego wejścia i wyjścia.

Kod 32+powinien być interpretowany +przez tłumacza jako 32 s. Po prostu zastąp je ręcznie, jeśli Twój tłumacz nie obsługuje RLE.

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

Wersja rozszerzona (nie RLE): (91 bajtów)

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

Kod zakłada, że ​​EOF jest zakodowany jako 0.

Wyjaśnienie

Używany jest następujący układ:

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

Gdzie xjest drukowany bajt ASCII, ajest znakiem ze standardowego wejścia i flagwynosi 1, jeśli abył spacją.

>,            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 Ponieważ wszystko powinno mieć implementację typu „bzdura”.
— Pharap

Czy „Run Length Encoded Brainfuck” to rzeczywiście osobny język? Nie mogę znaleźć tłumacza.
— mbomb007

3

Java 8: 60 bajtów

Używanie lambda w Javie 8 (75 bajtów):

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

A jeśli zezwolisz na import statyczny (z którego niektórzy tutaj korzystali), będzie to (61 bajtów):

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

Trochę krótsza wersja korzystająca z pętli for (60 bajtów):

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

2
Co, faktycznie zastąpili potworność znaną jako klasa anonimowa? Niesamowite.
— patrz

@Sieg tak Java ma teraz lambdas / zamknięcia, ale jest to głównie cukier syntetyczny oprócz anonimowych klas ... (oczywiście)
— Roy van Rijn

3

Clojure 63 (lub 57)

Implikacja All-Clojure:

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

Z interopem Java:

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

Sesja REPL:

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$

Co? Nie mamy tutaj żadnych wymyślnych funkcji binarnych do dziesiętnych. Zrób to sam!

Liczę nowy wiersz (który moim zdaniem jest konieczny, aby uzyskać if-then-else bez an END IF) jako jeden bajt na ten meta post . Nie wiem, czy QB64 w systemie Windows zaakceptuje plik kodu w ten sposób, czy nie. Prawdopodobnie nie ma to większego znaczenia.


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

jak uruchamiasz nodejs ze zgodnością z es6? najnowszy wciąż nie obsługuje dla mnie funkcji lambda
— be

Funkcje @bebe Arrow są zaimplementowane w v8, ale nie są jeszcze zintegrowane z węzłem. Zmienię mój post.
— cPu1

@ cPu1 pracują dla mnie
— nazwa użytkownika.ak

2

JavaScript 111

Dokonuje konwersji liczb bez analizy lub analizy. Czytanie ciągu wstecz i liczenie bitów ustawia bit x, jeśli jest jeden. Po znalezieniu spacji liczba jest konwertowana na znak i rozpoczyna się nowa liczba 0 w celu ustawienia bitów.

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 za zrobienie tego w staromodny sposób - zainspirowało mnie również do napisania wersji QBasic.
— DLosc

Niepoprawny, musi to być funkcja lub pełny program (taki, który pobiera dane wejściowe)
— tylko ASCII

2

Groovy 64

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

2

CJam, 11 bajtów

NS/{:~2bc}/

s nie jest prawidłową nazwą zmiennej w CJam, więc zamiast tego wybrałem N.

Wypróbuj online.

Przykładowy przebieg

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

Jak to działa

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 importów (?))

Oto moja pierwsza próba golfa w Haskell.

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

Musisz zaimportować Data.Char

użycie (w 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"

Wyjaśnienie:

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

Mam nadzieję, że poprawnie przestrzegałem konwencji punktacji dotyczących importu. Jeśli nie, możesz edytować poprawkę. Traktowałem plik „: m + Data.Char” potrzebny do zaimportowania do ghci jako 13.
— ballesta25

1

GNU Sed, 19 bajtów

Zainspirowany doskonałą odpowiedzią @Digital Trauma.

Grał w golfa

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

Test

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

Hello World

1

Pyth, 7 bajtów (niekonkurencyjny)

smCid2c

Pobiera dane wejściowe jako ciąg.

Spróbuj!


Oznaczono jako niekonkurencyjne, ponieważ język jest nowszy niż wyzwanie.
— mbomb007

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.