Converter uma sequência de caracteres binários nos equivalentes ASCII


27

Pegue uma sequência de caracteres binários separados por um espaço e converta-a em uma sequência ASCII.

Por exemplo...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Seria convertido para ...

Hello World

A cadeia binária será armazenada em uma variável chamada s.

Este é um desafio do código-golfe, por isso a solução mais curta vence.


15
+1 para fazer um desafio sem história e outras bugigangas, direto ao ponto
bebe

9
@bebe Fripperies fantásticas fictícias formam metade da diversão.
Qd

Olá. Vamos imaginar que sua tecnologia é tão avançada que não suporta ASCII. Seria permitido converter para a codificação de caracteres nativos ou teria que converter ASCII para a codificação de caracteres nativos? Eu estou pensando ZX81aqui
Shaun Bebbers

Respostas:


10

Ruby, 36 32

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

Ou 31

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

Otimizações graças a Chron


1
Você pode substituir .join""por *""salvar alguns caracteres. Você também pode fazer isso com gsub em vez de split + map + join, algo como: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 caracteres).
Paul Prestidge 27/07/2014

2
s.gsub(/\d+./){$&.to_i(2).chr}funciona e é 30 caracteres, não tenho idéia do por que funciona. O .não deve corresponder da última vez, mas corresponde.
30414 addison

10

JavaScript (ES6) 49 55 56 64

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

Editar Aceitando a sugestão @bebe - obrigado
Edit2 Não sabia sobre literal numérico binário - obrigado @kapep
Edit3 Wow 6, não 4 bytes salvos thx @ETHproductions

Explicação conforme solicitado nos comentários

String.replace pode levar 2 argumentos:

  • expressão regular /\d+./g: um ou mais dígitos seguidos por um caractere diferente - o sinalizador g especifica para pesquisar o padrão mais de uma vez
  • uma função, aqui especificada no formato de seta, em que o argumento (x) será a sequência encontrada (a sequência de dígitos eventualmente seguida por um espaço) e o valor da função será substituído (nesse caso, o caractere único de o código).

Vale ressaltar que no final da string o regexp corresponde à sequência de dígitos sem um espaço à direita, nesse caso o ponto corresponde ao último dígito. Tente '123'.match (/ (\ d +) ./) para verificar.

(Ainda) um dos mais detalhados trechos de javascript de todos os tempos ...
(atribuição à string s não contada)

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

Você pode explicar o que /\d+./g,x=>faz?
Izlin 28/07/14

1
@izlin eu adicionei alguma explicação para a resposta
edc65

Eu sei que esta é uma velha resposta, mas você pode mudar eval('0b'+x)para '0b'+x-0salvar 4 bytes.
ETHproductions

8

Bash + utilitários linux comuns, 25 bytes

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

explicação dc

  • empurre 2 para a pilha; pop e use como raiz de entrada
  • pressione a string de entrada para empilhar (todos os valores de uma vez)
  • Defina a macro recursiva mpara:
    • pop e, em seguida, imprima o valor como ASCII
    • empurre a profundidade da pilha para empilhar
    • pressione 0 para empilhar
    • pop top 2 valores da pilha; compare e chame a mmacro se a pilha não estiver vazia
  • parte superior duplicada da pilha (definição de macro)
  • pop e salve a macro para mregistrar
  • pop e executar macro

Como colocamos a string binária inteira na pilha primeiro, quando exibimos cada valor, terminamos com a string invertida. Então, usamos o revutilitário para corrigir isso.

Exemplo de uso:

$ 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: Não encontrou a outra resposta do PowerShell. Mas existe essencialmente apenas uma maneira de resolver isso.


7

C - 57 43 38/31

Versão de 38 bytes:

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

Ou apenas 31 bytes se s for um ponteiro:

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

Eu não acho que é exatamente assim que o loop for e while deve ser usado ... mas funciona.


6

Pyth , 12

smCv+"0b"dPZ

Observe que s não é uma variável legal em Pyth, então usei Z em vez disso.

Explicação:

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

Exemplo:

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

O fato de ele não usar espaços em branco na formatação (aqui está olhando para você Python) é um grande +1
Pharap

@Pharap Sim, uma maneira de olhar para Pyth é do Python com todos os elementos que o tornam tomar mais caracteres removidos, como tokens de espaços, parênteses, multi-caráter, etc.
isaacg

Não conheço Pyth, mas ele não salvaria 4 caracteres para usar id2no lugar de v+"0b"d? De qualquer forma, isso é ilegível e legal.
DLosc

@DLosc Adicionei essa função ao Pyth depois que essa pergunta foi feita, em grande parte devido a essa pergunta. Seria mais curto com o Pyth atual, mas o Pyth atual não é permitido para esse desafio.
Isaacg #

Entendo. Eu me perguntei se poderia ser algo assim.
DLosc

6

código de máquina x86 no DOS - 22 bytes

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

Como não existem variáveis ​​de string reais no código da máquina (e, em particular, nenhuma variável chamada " s"), decidi pelo stdin como entrada.

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

Loop simples sobre string binária em $ s. Ter que incluir o [convert] mata minha pontuação.

Edição: Existe realmente apenas uma maneira de conseguir isso em Powershell, wowie. Joey e eu tivemos a mesma resposta trabalhando de forma independente!

Entrada:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Saída:

Hello World

1
Você pode usar o operador de divisão unária, salvando três caracteres (quando nossas respostas são idênticas ... grande surpresa ;-)).
Joey

@ Joey Ohh, bom ponto! Não acredito que perdi isso. Você recebe o +1 de mim por entender isso, obrigado!
fuandon

5

Mathematica, 52 bytes

Ah, os adoráveis ​​nomes de funções do Mathematica

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

5

Perl 33 32

Edit: Solução atualizada, 32.

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

Solução anterior (33):

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

ou

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

Teste:

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

Teste:

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

Explicação:

                  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

Python shell  44  40 caracteres

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

Obrigado pela ajuda Griffin .


() .join (chr (int (x, 2)) para x em s.split ())
Griffin

4

APL (15)

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

Teste:

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

Explicação:

  • ⍎s: avaliar s, transformando-o em uma matriz de números inteiros. As matrizes são escritas como números separados por espaços, portanto, isso é dividido s.
  • {... : para cada elemento:
    • ⍕⍵: transformar o número novamente em uma sequência
    • ⍎¨: avalie cada dígito individual, fornecendo uma sequência de bits
    • 2⊥: decodificação base-2, fornecendo os números
  • ⎕UCS: obtém o caractere para cada número

A menos que especificado de outra forma você deve contar bytes em vez de caracteres: codegolf.stackexchange.com/tags/code-golf/info :)
Averroes

1
@Averroes: os ajustes da APL conjunto de caracteres em um byte com espaço para reposição: frankenstein.dns.org.uk/~marinus/aplcharset.png
marinus

Ah, eu não sabia disso. Minha culpa. Desculpe!
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 29/03

@ JörgHülsermann, a codificação pode pular zeros à esquerda, portanto str_split($s,8), não funcionará. foreach(explode(' ',$s)as$v)echo chr(bindec($v));seria válido, mas não pretendo editar uma das minhas primeiras respostas do PPGC que claramente não é realmente um jogo de golfe. Obrigado mesmo assim!
Christoph

4

Baco , 25 bytes

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

Explicação:

S,' 'j divida a String S pelo espaço vazio e a converta em um bloco (algum tipo de matriz).

:A= obter o bloco anterior e atribuí-lo a uma variável.

(),A¨ para cada elemento em A

Ö,2,10b Leia o elemento atual (represente por Ö ) na base 2 e transforme-o na base 10.

:c obtenha o valor anterior e imprima como char



3

C - 63

como C não possui conversor de base 2 na biblioteca padrão: teste aqui
edite: existe, eu sou burra demais para saber sobre isso

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

3

Brainfuck codificado em comprimento de execução, 49 bytes

Como não existem variáveis ​​no Brainfuck, apenas usei entrada e saída padrão.

O código 32+deve ser interpretado como 32 +s pelo intérprete. Apenas substitua-os manualmente se o seu intérprete não suportar RLE.

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

Versão expandida (não RLE): (91 bytes)

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

O código assume que o EOF é codificado como 0.

Explicação

O seguinte layout é usado:

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

Onde xestá o byte ASCII a ser impresso, aé o caractere a da entrada padrão e flagé 1 se houver aum espaço.

>,            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 Porque tudo deve ter uma implementação cerebral.
Pharap

"Brainfuck codificado em comprimento de execução" é um idioma separado real? Não consigo encontrar um intérprete.
mbomb007

3

Java 8: 60 bytes

Usando lambdas no Java 8 (75 bytes):

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

E se você permitir importações estáticas (usadas por alguns aqui), é (61 bytes):

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

Uma versão um pouco mais curta usando o loop for (60 bytes):

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

2
Na verdade, eles substituíram a monstruosidade conhecida como classe anônima? Impressionante.
see

@Sieg sim Java tem lambdas / fechamentos, bem como agora, mas é principalmente açúcar sintética no topo de classes anônimas ... (obviamente)
Roy van Rijn

3

Clojure 63 (ou 57)

O implemento all-Clojure:

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

Com interoperabilidade Java:

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

Sessão 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$

O que? Não temos funções sofisticadas de binário para decimal aqui. Faça Você Mesmo!

Estou contando a nova linha (que acho necessária para obter o if-then-else sem um END IF) como um byte, por esta meta postagem . Não sei se o QB64 no Windows aceitaria um arquivo de código dessa maneira ou não. Provavelmente não importa muito.


2

NodeJS62

Buffer(s.split(' ').map(function(a){return parseInt(a,2)}))+''

PHP75

array_reduce(explode(' ', $b),function($a,$b){return $a.chr(bindec($b));});

how do you run nodejs with es6 compatibility? the latest one still does not support lambda functions for me
bebe

@bebe Arrow functions are implemented in v8 but they aren't integrated with node yet. I'll edit my post.
c.P.u1

@c.P.u1 they work for me
username.ak

2

JavaScript 111

This does the number conversion without parseInt or eval. Reading the string backwards and counting bits it set's bit x if it's a one. When a space is found a the number is converted to a char and a new 0 number is started for setting bits.

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 for doing it the old-fashioned way--inspired me to write a QBasic version, too.
DLosc

Invalid, needs to be a function or full program (one that takes input)
ASCII-only

2

Groovy 64

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

2

CJam, 11 bytes

NS/{:~2bc}/

s isn't a legal variable name in CJam, so I chose N instead.

Try it online.

Example run

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

How it works

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 imports (?))

Here's my first golf attempt in Haskell.

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

You need to import Data.Char

usage (in 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"

Explanation:

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

Hopefully I've followed scoring conventions correctly regarding imports. Feel free to edit in a correction if I haven't. I treated the ":m +Data.Char" needed to import in ghci as 13.
ballesta25

1

GNU Sed, 19 bytes

Inspired by an excellent @Digital Trauma answer.

Golfed

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 bytes (non-competing)

smCid2c

Takes input as string.

Try it!


Marked non-competing because the language is newer than the challenge.
mbomb007

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.