Konversi string karakter biner ke ASCII setara

27

Ambil string karakter biner yang dipisahkan oleh spasi, dan ubah menjadi string ASCII.

Sebagai contoh...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Akan dikonversi ke ...

Hello World

String biner akan disimpan dalam variabel yang disebut s.

Ini adalah tantangan kode-golf sehingga solusi terpendek menang.

James Williams
sumber
15
1 untuk membuat tantangan tanpa cerita dan kegagalan lainnya, langsung pada intinya
bebe
9
@bebe Fripperies fantastik fiktif membentuk setengah kesenangan.
qwr
Halo. Mari kita bayangkan bahwa teknologi Anda sangat canggih sehingga tidak mendukung ASCII. Apakah diizinkan untuk mengonversi ke pengkodean karakter asli, atau apakah harus mengonversi ASCII ke pengkodean karakter asli? Saya sedang berpikir di ZX81sini.
Shaun Bebbers

Jawaban:

10

Ruby, 36 32

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

Atau 31

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

Optimalisasi berkat Chron

Kroltan
sumber
1
Anda dapat menggantikan .join""untuk *""menyimpan beberapa karakter. Anda juga dapat melakukannya dengan gsub alih-alih split + map + join, sesuatu seperti: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 karakter).
Paul Prestidge
2
s.gsub(/\d+./){$&.to_i(2).chr}bekerja dan 30 karakter, saya tidak tahu mengapa itu berhasil. The .tidak harus sesuai dengan terakhir kali tetapi tidak.
addison
10

JavaScript (ES6) 49 55 56 64

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

Edit Menerima saran @bebe - terima kasih
Edit2 Tidak tahu tentang literal angka biner - terima kasih @kapep
Edit3 Wow 6 tidak 4 byte disimpan thx @ETHproductions

Penjelasan seperti yang diminta dalam komentar

String.replace dapat mengambil 2 argumen:

  • ekspresi reguler /\d+./g: satu atau lebih digit diikuti oleh satu karakter yang berbeda - bendera g menentukan untuk mencari pola lebih dari sekali
  • sebuah fungsi, di sini ditentukan dalam format panah, di mana argumen (x) akan menjadi string yang ditemukan (urutan digit akhirnya diikuti oleh spasi) dan nilai fungsi adalah apa yang diganti (dalam kasus ini, karakter tunggal dari Kode).

Perlu dicatat bahwa pada akhir string regexp cocok dengan urutan digit tanpa spasi tambahan, dalam hal ini titik cocok dengan digit terakhir. Coba '123'.match (/ (\ d +) ./) untuk memverifikasi.

(Tetap) salah satu potongan javascript paling verbose yang pernah ...
(Penugasan ke string s tidak dihitung)

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
sumber
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
Bisakah Anda jelaskan apa /\d+./g,x=>fungsinya?
izlin
1
@izlin Saya menambahkan beberapa penjelasan untuk jawabannya
edc65
Saya tahu ini adalah jawaban lama, tetapi Anda dapat mengubah eval('0b'+x)ke '0b'+x-0untuk menyimpan 4 byte.
ETHproduk
8

Bash + utilitas linux umum, 25 byte

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

penjelasan dc

  • dorong 2 ke tumpukan; pop dan gunakan sebagai input radix
  • dorong input string ke stack (semua nilai sekaligus)
  • Tentukan makro rekursif muntuk:
    • pop, lalu cetak nilai sebagai ASCII
    • dorong kedalaman tumpukan ke tumpukan
    • tekan 0 untuk menumpuk
    • pop top 2 nilai stack; bandingkan dan panggil mmakro jika tumpukan tidak kosong
  • duplikat puncak tumpukan (definisi makro)
  • pop dan simpan makro untuk mmendaftar
  • pop dan jalankan makro

Karena kita mendorong seluruh string biner ke stack terlebih dahulu, ketika kita memunculkan setiap nilai, kita berakhir dengan string yang dibalik. Jadi kami menggunakan revutilitas untuk memperbaikinya.

Contoh penggunaan:

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

PowerShell, 49

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

EDIT: Tidak melihat jawaban PowerShell lainnya. Tetapi pada dasarnya hanya ada satu cara untuk menyelesaikan ini.

Joey
sumber
7

C - 57 43 38/31

Versi 38 Byte:

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

Atau hanya 31 byte jika s adalah pointer:

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

Saya tidak berpikir ini persis bagaimana untuk dan sementara loop seharusnya digunakan ... tetapi berfungsi.

Ian D. Scott
sumber
6

Pyth , 12

smCv+"0b"dPZ

Perhatikan bahwa s bukan variabel hukum dalam Pyth, jadi saya menggunakan Z sebagai gantinya.

Penjelasan:

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

Contoh:

=Z"<the binary string from above>"smCv+"0b"dPZ
Hello World
isaacg
sumber
Fakta itu tidak menggunakan spasi putih dalam format (di sini melihat Anda Python) adalah +1 utama
Pharap
@Pharap Ya, salah satu cara untuk melihat Pyth adalah Python dengan semua elemen yang membuatnya mengambil lebih banyak karakter, seperti spasi, tanda kurung, token multi-karakter, dll.
isaacg
Saya tidak tahu Pyth, tetapi akan tidak Hemat 4 karakter untuk digunakan id2di tempat v+"0b"d? Bagaimanapun, ini tidak dapat dibaca dan keren.
DLosc
@Dosc saya menambahkan fungsi itu ke Pyth setelah pertanyaan ini diajukan, sebagian besar karena pertanyaan ini. Ini akan lebih pendek dengan Pyth hari ini, tetapi Pyth hari ini tidak diperbolehkan untuk tantangan ini.
isaacg
Saya melihat. Saya bertanya-tanya apakah itu mungkin seperti itu.
DLosc
6

kode mesin x86 pada 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                                 |...!..|

Karena tidak ada variabel string nyata dalam kode mesin (dan khususnya, tidak ada variabel bernama " s"), saya memilih stdin sebagai input.

Input 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
sumber
6

Powershell ( 52 49)

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

Simpul sederhana di atas string biner dalam $ s. Namun harus memasukkan [konversi] membunuh skor saya.

EDIT: Hanya ada satu cara untuk melakukan ini di Powershell, wowie. Joey dan saya sama-sama mendapat jawaban yang sama dengan bekerja secara mandiri!

Memasukkan:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Keluaran:

Hello World
fuandon
sumber
1
Anda dapat menggunakan operator pemisah unary, menyimpan tiga karakter (pada titik mana jawaban kami identik ... kejutan besar ;-)).
Joey
@ Joey Ohh, poin bagus! Tidak percaya saya melewatkan itu. Anda mendapatkan +1 dari saya karena menangkap itu, terima kasih!
fuandon
5

Mathematica, 52 byte

Ah, nama fungsi Mathatica yang indah

f=FromCharacterCode[#~FromDigits~2&/@StringSplit@#]&
Martin Ender
sumber
5

Perl 33 32

Edit: Solusi yang diperbarui, 32.

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

Solusi sebelumnya (33):

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

atau

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

Uji:

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

J (23)

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

Uji:

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

Penjelasan:

                  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
sumber
4

Golfscript - 21

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

Anda bisa mengujinya di sini .

Kyle McCormick
sumber
4

Kerang Python  44  40 karakter

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

Terima kasih atas bantuan Griffin .

James Williams
sumber
'' .join (chr (int (x, 2)) untuk x dalam s.split ())
Griffin
4

APL (15)

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

Uji:

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

Penjelasan:

  • ⍎s: mengevaluasi s, mengubahnya menjadi array bilangan bulat. Array ditulis sebagai angka yang dipisahkan oleh spasi, jadi ini terbagis .
  • {... : untuk setiap elemen:
    • ⍕⍵: ubah nomor kembali menjadi string
    • ⍎¨: mengevaluasi setiap digit individu, memberikan bitstring
    • 2⊥: base-2 decode, memberikan angka
  • ⎕UCS: dapatkan karakter untuk setiap nomor
marinus
sumber
Kecuali ditentukan lain, Anda harus menghitung byte alih-alih karakter: codegolf.stackexchange.com/tags/code-golf/info :)
Averroes
1
@Averroes: charset APL cocok dalam satu byte dengan ruang yang tersisa: frankenstein.dns.org.uk/ ~
marinus
Ah, saya tidak tahu itu. Salahku. Maaf!
Averroes
4

PHP (61)

<?=join(array_map('chr',array_map('bindec',explode(' ',$s))))
Christoph
sumber
foreach(str_split($s,8)as$v)echo chr(bindec($v));
Jörg Hülsermann
@ JörgHülsermann pengkodean dapat melewati nol di depan karena itu str_split($s,8)tidak akan berfungsi. foreach(explode(' ',$s)as$v)echo chr(bindec($v));akan valid tetapi saya tidak berencana untuk mengedit salah satu jawaban PPGC pertama saya yang jelas tidak benar-benar golf. Bagaimanapun, terima kasih!
Christoph
4

Bacchus , 25 byte

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

Penjelasan:

S,' 'j pisahkan String S dengan ruang kosong dan mengubahnya menjadi sebuah blok (semacam array).

:A= dapatkan Blok sebelumnya dan asumsikan ke variabel A.

(),A¨ untuk Setiap elemen dalam A

Ö,2,10b Baca elemen saat ini (diwakili oleh Ö ) di basis 2 dan ubah menjadi basis 10.

:c dapatkan nilai sebelumnya dan cetak sebagai char

Averroes
sumber
3

GolfScript 23

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

Tes online di sini .

Cristian Lupascu
sumber
3

C - 63

karena C tidak memiliki basis 2 converter di perpustakaan standar: tes di sini
edit: ada, aku terlalu bodoh untuk mengetahuinya

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

Jalankan Panjang Encoded Brainfuck, 49 byte

Karena tidak ada variabel di Brainfuck, saya hanya menggunakan input dan output standar saja.

Kode 32+harus ditafsirkan sebagai 32 +detik oleh penerjemah. Ganti saja secara manual jika juru bahasa Anda tidak mendukung RLE.

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

Versi yang diperluas (non-RLE): (91 byte)

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

Kode mengasumsikan bahwa EOF dikodekan sebagai 0.

Penjelasan

Tata letak berikut digunakan:

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

Di mana xbyte ASCII yang akan dicetak, aadalah karakter dari input standar dan flag1 jika aadalah spasi.

>,            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
sumber
1
+1 Karena semuanya harus memiliki implementasi brainfuck.
Pharap
Apakah "Run Length Encoded Brainfuck" adalah bahasa terpisah yang sebenarnya? Saya tidak dapat menemukan penerjemah.
mbomb007
3

Java 8: 60 byte

Menggunakan lambdas di Java 8 (75 byte):

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

Dan jika Anda mengizinkan impor statis (yang sebagian digunakan di sini) itu adalah (61 byte):

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

Versi kecil yang lebih pendek menggunakan for loop (60 bytes):

for(String n:s.split(" ")){out.print((char)parseInt(n,2));}
Roy van Rijn
sumber
2
Apa, mereka benar-benar membuat pengganti monstrositas yang dikenal sebagai kelas anonim? Luar biasa.
seequ
@ Sieg ya Jawa memiliki lambdas / penutupan sekarang juga, tetapi sebagian besar gula sintetis di atas kelas anonim ... (jelas)
Roy van Rijn
3

Clojure 63 (atau 57)

Implan all-Clojure:

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

Dengan Java interop:

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

Sesi 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
sumber
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$

Apa? Kami tidak memiliki fungsi biner hingga desimal di sini. Lakukan sendiri!

Saya menghitung baris baru (yang saya pikir perlu untuk mendapatkan if-then-else tanpa END IF) sebagai satu byte, per posting meta ini . Saya tidak tahu apakah QB64 di Windows akan menerima file kode seperti itu atau tidak. Mungkin tidak masalah.

DLosc
sumber
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
sumber
bagaimana Anda menjalankan nodejs dengan kompatibilitas es6? yang terbaru masih tidak mendukung fungsi lambda untuk saya
bebe
Fungsi @bebe Arrow diimplementasikan di v8 tetapi belum terintegrasi dengan node. Saya akan mengedit posting saya.
cPu1
@ cPu1 mereka bekerja untuk saya
username.ak
2

JavaScript 111

Ini melakukan konversi angka tanpa parseInt atau eval. Membaca string ke belakang dan menghitung bit-bit itu mengatur bit x jika itu satu. Ketika spasi ditemukan angka dikonversi ke char dan angka 0 baru dimulai untuk pengaturan bit.

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
sumber
1
+1 karena melakukannya dengan cara kuno - mengilhami saya untuk menulis versi QBasic juga.
DLosc
Tidak valid, harus berupa fungsi atau program lengkap (yang mengambil input)
ASCII
2

Groovy 64

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

CJam, 11 byte

NS/{:~2bc}/

s bukan nama variabel hukum di CJam, jadi saya memilih N sebagai gantinya.

Cobalah online.

Contoh dijalankan

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

Bagaimana itu bekerja

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
sumber
2

Haskell - 48 (+13 impor (?))

Ini usaha golf pertama saya di Haskell.

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

Anda perlu mengimpor Data.Char

penggunaan (dalam 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"

Penjelasan:

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
sumber
Semoga saya mengikuti konvensi penilaian dengan benar terkait impor. Jangan ragu untuk mengedit dalam koreksi jika saya belum. Saya memperlakukan ": m + Data.Char" yang diperlukan untuk mengimpor dalam ghci sebagai 13.
ballesta25
1

GNU Sed, 19 byte

Terinspirasi oleh jawaban Trauma Digital yang sangat baik .

Golf

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

Uji

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

Hello World
zeppelin
sumber
1

Pyth, 7 byte (tidak bersaing)

smCid2c

Mengambil input sebagai string.

Cobalah!

KarlKastor
sumber
Ditandai non-bersaing karena bahasa lebih baru daripada tantangan.
mbomb007
1

05AB1E , 4 byte (tidak bersaing)

Disimpan 3 byte berkat @Emigna

#CçJ

Cobalah online!

Guci Gurita Ajaib
sumber
1
#CçJjuga berfungsi. Meskipun dalam kedua ini dan versi Anda, Anda perlu ð¡bukannya #jika input hanya 1 char.
Emigna