Перетворити рядок двійкових символів в еквіваленти ASCII


27

Візьміть рядок двійкових символів, розділених пробілом, і перетворіть його в рядок ASCII.

Наприклад...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Перетвориться на ...

Hello World

Двійковий рядок буде зберігатися у змінній, що називається s.

Це проблема з кодовим гольфом, тому найкоротше рішення виграє.


15
+1 за те, щоб зробити виклик без розповіді та інших вигуків, прямо до
суті

9
@bebe Вигадані фантастичні вигуки утворюють половину задоволення.
qwr

Привіт. Давайте уявимо, що ваша технологія настільки вдосконалена, що не підтримує ASCII. Чи буде дозволено перетворити на кодування корінних символів, чи доведеться перетворити ASCII в кодування нативного символу? Я ZX81тут думаю .
Шон Бебберс

Відповіді:


10

Рубі, 36 32

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

Або 31

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

Оптимізація завдяки Chron


1
Можна замінити .join""на , *""щоб заощадити кілька символів. Ви також можете це зробити за допомогою gsub замість розділення + map + приєднання, щось на кшталт: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 знаків).
Пол Престиждж

2
s.gsub(/\d+./){$&.to_i(2).chr}працює, і це 30 символів, я поняття не маю, чому він працює. Це .не повинно відповідати востаннє, але це є.
Аддісон

10

JavaScript (ES6) 49 55 56 64

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

Редагувати Приймаюча пропозиція @bebe - спасибі
Edit2 Не знала про двійковий числовий літерал - дякую @kapep
Edit3 Нічого не 4 байти збережено thx @ETHproductions

Пояснення, як вимагається в коментарях

String.replace можна взяти 2 аргументи:

  • регулярний вираз /\d+./g: одна чи кілька цифр, за якими слідує один інший символ - прапор g вказують для пошуку шаблону не один раз
  • функція, вказана тут у форматі стрілки, де аргументом (x) буде знайдений рядок (послідовність цифр зрештою слідує пробілом), а значення функції - те, що замінено (в даному випадку - єдиний символ з кодекс).

Варто відзначити, що в кінці рядка регулярний вирівнювання відповідає послідовності цифр без пробілу, в цьому випадку крапка відповідає останній цифрі. Спробуйте "123'.match (/ (\ d +) ./) для підтвердження.

(Все-таки) один з більш багатослівних фрагментів javascript коли-небудь ...
(Присвоєння рядку s не враховується)

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
беб

2
s.replace(/\d+./g,x=>String.fromCharCode(eval("0b"+x)))55
капекс

Чи можете ви поясніть, що /\d+./g,x=>робить?
izlin

1
@izlin Я додав пояснення у відповідь
edc65

Я знаю , що це старий відповідь, але ви можете змінити , eval('0b'+x)щоб '0b'+x-0врятувати 4 байта.
ETHproductions

8

Bash + загальні утиліти Linux, 25 байт

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

постійне пояснення

  • натисніть 2 до стека; поп і використовувати як вхідний радіакс
  • натиснути вхідний рядок для стека (всі значення одразу)
  • Визначте рекурсивний макрос mдля:
    • pop, а потім значення друку як ASCII
    • просунути глибину стека для укладання
    • натисніть 0 для складання
    • pop top 2 значення стека; порівняти та викликати mмакрос, якщо стек не порожній
  • дублікат верхньої частини стека (визначення макросу)
  • вискочити та зберегти макрос для mреєстрації
  • вискакувати та виконати макрос

Оскільки ми спочатку підсуваємо весь двійковий рядок до стеку, коли ми вискакуємо кожне значення, ми закінчуємо перетвореним рядком. Тому ми використовуємо revутиліту, щоб виправити це.

Приклад використання:

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

EDIT: Іншої відповіді PowerShell не побачив. Але існує по суті лише один спосіб вирішення цього питання.


7

С - 57 43 38/31

38-байтна версія:

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

Або лише 31 байт, якщо s - покажчик:

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

Я не думаю, що це саме так, і коли цикл повинен використовуватися ... але це працює.


6

Піта , 12

smCv+"0b"dPZ

Зауважте, що s не є юридичною змінною в Pyth, тому я використовував Z замість цього.

Пояснення:

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

Приклад:

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

Те, що він не використовує пробіл у форматуванні (ось дивиться на вас Python), є головним +1
Pharap

@Pharap Так, один із способів дивитися на Pyth - це Python з усіма елементами, які змушують видалити більше символів, як пробіл, дужки, багато символи, лексеми тощо
isaacg

Я не знаю Pyth, але хіба це не збереже 4 символи для використання id2замість v+"0b"d? У будь-якому випадку це і нечитабельно, і класно.
DLosc

@DLosc Я додав цю функцію Pyth після того, як було задано це питання, значною мірою завдяки цьому питанню. Це було б коротше, ніж сьогоднішній Pyth, але нинішній Pyth заборонений для цього виклику.
isaacg

Розумію. Мені було цікаво, чи може це бути щось подібне.
DLosc

6

машинний код x86 на DOS - 22 байти

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

Оскільки в машинному коді немає реальних змінних рядків (і, зокрема, немає змінних з назвою " s"), я погодився на stdin як вхідний.

Вхід 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)})

Простий цикл над двійковим рядком у $ s. Включення [конвертувати] вбиває мій рахунок.

EDIT: Насправді існує лише один спосіб усунути це в Powershell, вауї. Joey і ми обоє отримали майже однакову відповідь, працюючи незалежно!

Вхід:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Вихід:

Hello World

1
Ви можете скористатися одинарним оператором розділення, зберігаючи три символи (в цей момент наші відповіді ідентичні ... великий сюрприз ;-)).
Joey

@Joey О, хороший момент! Не можу повірити, що я пропустив це. Ви отримуєте +1 від мене за те, що це зрозуміли, дякую!
fuandon

5

Математика, 52 байти

Ах, прекрасні назви функцій Mathematica

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

5

Перл 33 32

Редагувати: оновлене рішення, 32.

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

Попереднє рішення (33):

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

або

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

Тест:

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

Тест:

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

Пояснення:

                  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

Тест:

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

Пояснення:

  • ⍎s: оцінити s, перетворивши його на масив цілих чисел. Масиви записуються як числа, розділені пробілами, тому це розділяється s.
  • {... : для кожного елемента:
    • ⍕⍵: поверніть число назад у рядок
    • ⍎¨: оцінюйте кожну окрему цифру, даючи штрих
    • 2⊥: декодування base-2, даючи числа
  • ⎕UCS: отримати символ для кожного числа

Якщо не вказано інше, вам слід рахувати байти замість символів: codegolf.stackexchange.com/tags/code-golf/info :)
Averroes

1
@Averroes: гарнітура APL поміщається в байт із простором
marinus

Ах, я цього не знав. Моє ліжко. Вибачте!
Аверроес

4

PHP (61)

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

foreach(str_split($s,8)as$v)echo chr(bindec($v));
Йорг Гюльсерманн

@ JörgHülsermann кодування може пропустити провідні нулі, тому str_split($s,8)не буде працювати. foreach(explode(' ',$s)as$v)echo chr(bindec($v));було б справедливим, але я не планую редагувати одну з моїх перших відповідей PPGC, яка явно не справді гольфу. В будь-якому випадку, дякую!
Крістоф

4

Вакха , 25 байт

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

Пояснення:

S,' 'j розділити String S на порожній простір і перетворити його в блок (якийсь масив).

:A= отримати попередній блок і привласнити його змінній A.

(),A¨ для кожного елемента в A

Ö,2,10bПрочитайте поточний елемент (представляємо собою Ö) у базі 2 та перетворіть його на базу 10.

:c отримати попереднє значення та друкувати як char



3

С - 63

оскільки у C немає базового перетворювача в стандартній бібліотеці: перевірити тут
редагувати: є, я занадто дурний, щоб знати про це

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

3

Довжина коду, Brainfuck, 49 байт

Оскільки в Brainfuck немає змінних, я просто використав стандартний ввід та вихід.

Код 32+повинен інтерпретувати інтерпретатор як 32 +s. Просто замініть їх вручну, якщо ваш перекладач не підтримує RLE.

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

Розширена (не RLE) версія: (91 байт)

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

Код передбачає, що EOF кодується як 0.

Пояснення

Використовується такий макет:

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

Де xбайт ASCII для друку a- це символ зі стандартного вводу і flagдорівнює 1, якщо aбув пробіл.

>,            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 Тому що все повинно мати розумну реалізацію.
Фарап

Чи є "Run Run Encoded Brainfuck" фактичною окремою мовою? Я не можу знайти перекладача.
mbomb007

3

Java 8: 60 байт

Використання лямбда в Java 8 (75 байт):

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

І якщо ви дозволите статичний імпорт (який деякі тут використовуються), це (61 байт):

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

Трохи коротша версія, що використовується для циклу (60 байт):

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

2
Що, вони насправді зробили заміну чудовисько, відомому як анонімний клас? Дивовижно.
seequ

@Sieg Так, у Java зараз є і лямбда / закриття, але це, головним чином, синтетичний цукор поверх анонімних класів ... (очевидно)
Рой ван Рійн,

3

Clojure 63 (або 57)

Все-Clojure impl:

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

З інтеропом Java:

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

Сесія 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$

Що? Тут ми не маємо фантазійних двійкових до десяткових функцій. Зроби це сам!

Я рахую новий рядок (який, на мою думку, необхідний, щоб отримати if-then-else без an END IF), як один байт, за цей мета-пост . Я не знаю, чи QB64 в Windows прийняв би файл коду таким чином чи ні. Напевно, це не має великого значення.


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

як запускати nodejs із сумісністю es6? останній досі не підтримує лямбда-функцій для мене
bebe

Функції @bebe Arrow реалізовані в v8, але вони ще не інтегровані з вузлом. Я відредагую свою публікацію.
cPu1

@ cPu1 вони працюють для мене
username.ak

2

JavaScript 111

Це робить перетворення чисел без аналізу parseInt або eval. Читання рядка назад і підрахунок бітів, встановлених його біт x, якщо це один. Коли знайдеться пробіл, число перетворюється на знак char та починається нове число 0 для встановлення бітів.

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 за те, що це робив по-старому - надихнуло мене також написати QBasic версію.
DLosc

Недійсне, має бути функція або повна програма (та, яка бере вхід)
лише для ASCII


2

CJam, 11 байт

NS/{:~2bc}/

s не є юридичним ім'ям змінної у CJam, тому я обрав натомість N.

Спробуйте в Інтернеті.

Приклад виконання

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

Як це працює

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 імпорт (?))

Ось моя перша спроба гольфу в Хаскеллі.

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

Вам потрібно імпортувати Data.Char

використання (в 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"

Пояснення:

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

Сподіваюся, я правильно дотримувався конвенцій щодо імпорту. Не соромтесь редагувати виправлення, якщо я цього не зробив. Я поставив ": m + Data.Char", необхідного для імпорту в ghci, як 13.
ballesta25

1

GNU Sed, 19 байт

Натхненний чудовою відповіддю @Digital Trauma.

Гольф

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

Тест

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

Hello World


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.