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.