Transição de String para Bit


10

Tarefa

Dada uma sequência de entrada de um ou mais caracteres ASCII cujos pontos de código estão entre 0 e 128 (exclusivo), faça o seguinte:

  1. Converta cada caractere em seu código ASCII de 7 bits (se o código ASCII for menor que 7 bits, coloque os zero bits iniciais)
  2. Concatenar todos os bits (isso resulta em 7*nbits, onde né o número de caracteres)
  3. Para cada bit nesse fluxo de bits, imprima 1 se for diferente do bit anterior e imprima 0 caso contrário. O primeiro bit de saída é sempre 1.

Exemplo

Entrada:

Hi

Resultado:

11011001011101

Explicação:

A cadeia "Hi" possui os códigos ASCII

72 105

que em bits são:

1001000 1101001

E os indicadores de bits de transição:

11011001011101

Isso é código de golfe. O menor número de bytes vence.

Casos de teste

Caso de teste 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Caso de teste 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

Caso de teste 3 (crédito a Luis Mendo):

##
11100101110010

Parabéns a Luis Mendo pela solução mais curta com 9 bytes em MATL!


2
Caso de teste sugeriu ##(levando 0bit; algumas respostas atualmente falhar por causa disso)
Luis Mendo

4
Como isso é uma duplicata do desafio de codificação de Manchester? Estou esquecendo de algo?
Gastropner 10/07/19

2
O outro desafio diz a conversão de um fluxo de entrada de bits em um fluxo de saída de taxa dupla, com cada entrada '1' traduzida para '01' e cada entrada '0' traduzida para '10' . Portanto, não engane na minha opinião. Se um grande número de pessoas comentário upvote de @ gastropner acima eu posso un-dupe (ou qualquer outro usuário com essa capacidade)
Luis Mendo

11
@ Shagy: Ambos os casos de teste incluem um espaço, que possui apenas um único conjunto de bits, e não o sétimo. Portanto, não acho que a declaração do problema esteja garantindo que cada código ASCII tenha exatamente 7 bits de comprimento.
recursivo

11
@SmileAndNod Pensando bem, acho que você não precisa lidar com string vazia.
Just just 17/07/19

Respostas:


4

MATL , 9 bytes

Hj7&B!hdg

Experimente online!

Explicação

H     % Push 2
j     % Read line of input, unevaluated
7&B   % Convert to binary with 7 bits. Gives a 7-column matrix
!     % Transpose
h     % Concatenate horiontally. The matrix is read in column-major order
d     % Consecutive differences
g     % Convert to logical. Implicitly display

11
Este é o mais curto até agora. +1. É divertido ter um built-in para diferenças consecutivas.
justhalf


4

Japt -P , 11 bytes

Aproveita o fato de que os espaços podem ser coagidos para 0 no JavaScript ao tentar executar uma operação matemática ou, nesse caso, bit a bit nele.

c_¤ù7Ãä^ i1

Experimente ou execute todos os casos de teste

c_¤ù7Ãä^ i1     :Implicit input of string
c_              :Map codepoints
  ¤             :  Convert to binary string
   ù7           :  Left pad with spaces to length 7
     Ã          :End map
      ä^        :XOR consecutive pairs
         i1     :Prepend 1
                :Implicitly join and output

O de 7 bits significa que, se tiver 32 (para caractere de espaço), seria 0100000. Também o caractere% (37) seria0100101
justhalf

Está funcionando agora. +1
justhalf

2

CJam , 21 bytes

1q{i2b7Te[}%e__(;.^);

Experimente online!

Explicação

Mostrando a pilha com uma entrada de amostra de 5:

1 q      e# Push 1 and then the whole input: 1 "5"
{
  i      e# Convert to its char code: 1 [53]
  2 b    e# Convert to binary: 1 [[1 1 0 1 0 1]]
  7 T e[ e# Left-pad with 0 to length 7: 1 [[0 1 1 0 1 0 1]]
} %      e# Map this block over every character in the string
e_       e# Flatten array: 1 [0 1 1 0 1 0 1]
_ ( ;    e# Duplicate array and remove its first element: 1 [0 1 1 0 1 0 1] [1 1 0 1 0 1]
. ^      e# Element-wise xor: 1 [1 0 1 1 1 1 1]
) ;      e# Remove and pop the last element of the array: 1 [1 0 1 1 1 1]
         e# Stack implicitly printed: 1101111

Para verificar se um bit é diferente do bit anterior, criamos um vetor (elemento a elemento) xor entre a matriz de bits e a matriz de bits sem o primeiro elemento. Também removemos o último bit do resultado, porque ele é sempre o último bit da matriz mais longa inalterado.


2

APL (Dyalog Unicode) , 16 bytes SBCS

Programa completo. Solicita a string do stdin.

1,2≠/∊1↓¨11DR¨⍞

Experimente online!

 solicitação de entrada ("uma cotação em um console")

11⎕DR¨ altere cada caractere para bit-booleano D ata R ePresentation

1↓¨ solte o primeiro bit de cada

ε nlist (achatar)

2≠/ diferença pareada

1, Anexar um



2

Carvão , 25 bytes

⭆θ◧⍘℅鲦⁷←Wⅈ←I﹪⍘KD²←01 ²1

Experimente online! Link é a versão detalhada do código. Explicação:

⭆θ◧⍘℅鲦⁷←

Converta todos os caracteres em binários e preencha-os com um comprimento de 7 e imprima-os, mas deixe o cursor sobre o último dígito.

Wⅈ

Repita até que o cursor esteja sobre o primeiro dígito.

←I﹪⍘KD²←01 ²

Calcule se os dígitos são diferentes e substitua cada dígito pela diferença.

1

Sobrescreva o primeiro dígito com a 1.





1

Python 2 , 104 bytes

lambda w:reduce(lambda(A,P),C:(A+'10'[P==C],C),bin(reduce(lambda a,c:a*128+ord(c),w,1))[3:],('','x'))[0]

Experimente online!

Uma rápida facada.


Truque inteligente com a*128+ord(c)! Mas não o é reducee lambdatipo de caro?
Just just

1

Dardo , 213 168 bytes

f(s,{t,i}){t=s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList();for(i=t.length-1;i>0;i--)t[i]=t[i]==t[i-1]?'0':'1';t[0]='1';return t.join();}

One-liner anterior

f(String s)=>'1'+s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList().reversed.reduce((p,e)=>p.substring(0,p.length-1)+(p[p.length-1]==e?'0':'1')+e).split('').reversed.join().substring(1);

Experimente online!

Essa verbosidade e falta de ins fáceis de construir estão realmente matando essa. Ainda conseguiu puxar um forro embora.

  • -45 bytes por não usar um liner e um loop for


1

Kotlin , 182 bytes

var l='6'
fun f(b:String)=b.fold(""){t,i->t+"".a(i.toInt())}.map{if(l==it){l=it;0} else {l=it;1}}
fun String.a(v:Int):String=if(v<=0)"${this}0".reversed() else "${this}${v%2}".a(v/2)

Experimente online!

Espero poder melhorar isso em breve, sinto que deve haver alguns pontos a melhorar, mas não consigo pensar agora




1

Ruby -p , 50 bytes

gsub(/./){"%07b"%$&.ord}
gsub(/./){$`=~/#$&$/?0:1}

Experimente online!

Explicação

Primeira linha, igual à resposta da Value Ink :

gsub(/./){       $&    }   # Replace each character $&…
                   .ord    # …with its ASCII code…
                %          # …formatted as…
          "%07b"           # …binary digits padded to 7 places.

Segunda linha:

gsub(/./){      $&      }  # Replace each character $&…
          $`               # …if the text to its left…
            =~             # …matches…
              /#  $/       # …the Regexp /c$/ where "c" is the character…
                    ?0:1   # …with 0, or 1 otherwise.

No Ruby, você pode usar a interpolação em literais do Regexp, por exemplo /Hello #{name}/, e para variáveis ​​que começam com $ou @você pode omitir os chavetas, portanto, se eg $&for "0", o grawlixy /#$&$/se tornará /0$/.


1

K (ngn / k) , 9 13 bytes

Solução:

~=':,/(7#2)\'

Experimente online!

Explicação:

~=':,/(7#2)\' / the solution
           \' / convert each
      (   )   / do this together
       7#2    / 2 2 2 2 2 2 2
    ,/        / flatten
 =':          / equal to each-previous?
~             / not

Notas:

  • +4 bytes para suportar cadeias consistindo apenas em caracteres de 6 bits

Este parece falhar para entrada #por exemplo (apenas saída tem 6 bits)
Luis Mendo

@ streetster, você deseja publicar a versão fixa?
justhalf 11/07/19

1

Emojicode , 263 bytes

🏁🍇🔤🔤➡️🖍🆕s🔂b📇🆕🔡👂🏼❗️❗️🍇🍪s🔪🔡🔢b❗️➕128 2❗️1 7❗️🍪➡️🖍s🍉🔤?🔤➡️🖍🆕p🔂b s🍇↪️b🙌p🍇👄🔤0🔤❗️🍉🙅🍇👄🔤1🔤❗️🍉b➡️🖍p🍉🍉

Experimente online aqui.

Ungolfed:

🏁 🍇  💭 Main code block
    🔤🔤 ➡️ 🖍 🆕 s  💭 Start with s as the empty string
    🔂 b 📇 🆕 🔡 👂🏼  💭 For each byte b in the input ...
    ❗️ ❗️ 🍇
        🍪 s  💭 ... append ...
           🔪 🔡 🔢 b ❗️ ➕ 128  💭 ... b + 128 (this gives the leading zero(s) in case the binary representation of b is shorter than 7 digits) ...

                 2  💭 ... in binary ...
              ❗️
              1 7  💭 ... without the leading one ...
           ❗️
        🍪
        ➡️ 🖍 s  💭 ... to s
    🍉
    🔤?🔤 ➡️ 🖍 🆕 p  💭 This will be used as the previous character, by assigning it neither 0 nor 1 we assure the first bit output is always a one
    🔂 b s 🍇  💭 For each character in s:
        ↪️ b 🙌 p 🍇  💭 If it is the same as the previous character ...
            👄 🔤0🔤 ❗️  💭 ... output a zero ...
        🍉 🙅 🍇  💭  ... else ...
            👄 🔤1🔤 ❗️ 💭 ... output a one
        🍉
        b ➡️ 🖍 p  💭 And the current character becomes the new previous character.
    🍉
🍉


1

Python3.8 , 72 bytes

Solução:

lambda a:["10"[a==(a:=x)]for x in"".join(bin(ord(i)+128)[3:]for i in a)]

Explicação:

Desde que o Python 3.8 introduziu expressões de atribuição (em vez das instruções de atribuição padrão), eu queria usá-las em uma compreensão de lista que precisa lembrar o último item. Essa não é a melhor maneira de fazer isso, mas demonstra um método interessante de usar a expressão de atribuição.

O código cria uma função lambda que recebe o argumento necessário, que é a string a ser convertida. Quando chamada, a função prossegue da seguinte maneira. Todo caractere em a é convertido em seu código de caractere ao qual 128 é adicionado para lidar com caracteres de 6 bits (a representação binária sempre será de 8 bits e podemos cortar o primeiro bit). Esse número é convertido em binário e o cabeçalho (0x) e o 1 inicial da adição de 128 são cortados. Essas novas seqüências de caracteres são unidas em uma sequência maior.

Para cada caractere nessa nova seqüência de caracteres (que contém a representação concatenada de 7 bits do texto), é verificado se o caractere é igual ao caractere anterior. O que acontece com o primeiro personagem? O caractere do primeiro resultado sempre deve ser "1", portanto, apenas precisamos garantir que o que estiver na variável do último caractere não seja "1" nem "0". Fazemos isso reutilizando o parâmetro original agora que não o estamos mais usando. Isso pode ser um problema se a string original for um único "0" (um único "1" funciona), mas ignoraremos isso.

Durante a comparação, o caractere anterior foi avaliado primeiro; portanto, quando usamos a expressão de atribuição para definir a variável de caractere anterior para o caractere atual, isso não afeta a avaliação das expressões de comparação.

A comparação produz True ou False, que também pode ser usado como 1 ou 0, respectivamente, em Python, portanto, eles são usados ​​para procurar um "1" ou "0" em uma string


Você pode salvar alguns bytes usando literais formato string: bin(ord(i)+128)[3:]->f"{ord(i):07b}"
movatica

1

Tcl , 215 167 140 bytes

{{s {B binary} {X ~$w/64}} {join [lmap c [split $s {}] {$B scan $c c w;$B scan [$B format i [expr 2*$w^$w^$X<<7]] B7 r;set X $w;set r}] ""}}

Experimente online!

Usa turno por um e exclusivo - ou para detectar transições. Carrega lsb do caractere atual para msb do próximo caractere. Combina a saída para cada caractere juntando-se à lista retornada pelo lmap.

Usa lambdas com argumentos padrão para salvar bytes na inicialização e comandos repetidos.

Depende muito da ordem de operação. Funciona para cadeia vazia.


1

05AB1E (herdado) , 12 bytes

Çb7jð0:¥ÄJ1ì

Usa a versão herdada de 05AB1E, pois june implicitamente as seqüências de caracteres, o que requer um explícito Japós o jna nova versão de 05AB1E.

Experimente online ou verifique todos os casos de teste .

Explicação:

Ç             # Convert the (implicit) input-string to a list of ASCII code-points
              #  i.e. "Hi#" → [72,105,35]
 b            # Convert each integer to a binary string
              #  → ["1001000","1101001","100011"]
  7j          # Prepend each with spaces to make them length 7,
              # and join everything together to a single string implicitly
              #  → "10010001101001 100011"
    ð0:       # Replace all those spaces with 0s
              #  → "100100011010010100011"
       ¥      # Get the deltas of each pair of 1s/0s
              #  → [-1,0,1,-1,0,0,1,0,-1,1,-1,0,1,-1,1,-1,0,0,1,0]
        Ä     # Get the absolute value of this
              #  → [1,0,1,1,0,0,1,0,1,1,1,0,1,1,1,1,0,0,1,0]
         J    # Join them all together
              #  → "10110010111011110010"
          1ì  # And prepend a 1
              #  → "110110010111011110010"
              # (after which the result is output implicitly)

1

Haskell , 137 bytes

import Data.Char
b 0=[]
b n=odd n:b(n`div`2)
d x|x='1'|1<2='0'
c=('1':).map d.(zipWith(/=)<*>tail).concatMap(reverse.take 7.b.(+128).ord)

Experimente online!

O maior problema aqui é converter booleanos (resultado do XOR) em '0' / '1'.





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.