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.

James Williams
źródło
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

Kroltan
źródło
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)

edc65
źródło
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
$ 
Cyfrowa trauma
źródło
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.

Joey
źródło
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.

Ian D. Scott
źródło
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
isaacg
źródło
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
Matteo Italia
źródło
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
fuandon
źródło
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@#]&
Martin Ender
źródło
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'
hmatt1
źródło
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
marinus
źródło
4

Golfscript - 21

' '/{1/{~}%2base}%''+

Możesz to przetestować tutaj .

Kyle McCormick
źródło
4

Python shell  44  40 znaków

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

Dzięki za pomoc Griffin .

James Williams
źródło
'' .join (chr (int (x, 2)) for x in s.split ())
Griffin
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
marinus
źródło
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))))
Christoph
źródło
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

Averroes
źródło
3

GolfScript 23

' '/{[{49=}/]2base}%''+

Test online tutaj .

Cristian Lupascu
źródło
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;}
bebe
źródło
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
Hjulle
źródło
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));}
Roy van Rijn
źródło
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"
YosemiteMark
źródło
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.

DLosc
źródło
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));});
cPu1
źródło
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
}
wolfhammer
źródło
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("")}
markusw
źródło
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.                          ";
Dennis
źródło
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
ballesta25
źródło
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
zepelin
źródło
1

Pyth, 7 bajtów (niekonkurencyjny)

smCid2c

Pobiera dane wejściowe jako ciąg.

Spróbuj!

KarlKastor
źródło
Oznaczono jako niekonkurencyjne, ponieważ język jest nowszy niż wyzwanie.
mbomb007
1

05AB1E , 4 bajty (niekonkurujące)

Zaoszczędź 3 bajty dzięki @Emigna

#CçJ

Wypróbuj online!

Urna Magicznej Ośmiornicy
źródło
1
#CçJdziała również. Chociaż zarówno w tej, jak i twojej wersji potrzebujesz ð¡zamiast tego, #czy dane wejściowe mogą mieć tylko 1 znak.
Emigna