Transición de cadena a bit


10

Tarea

Dada una cadena de entrada de uno o más caracteres ASCII cuyos puntos de código están entre 0 y 128 (exclusivo), haga lo siguiente:

  1. Convierta cada carácter en su código ASCII de 7 bits (si el código ASCII es inferior a 7 bits, ponga los cero bits iniciales)
  2. Concatenar todos los bits (esto da como resultado 7*nbits donde nestá el número de caracteres)
  3. Para cada bit en este flujo de bits, imprima 1 si es diferente del bit anterior e imprima 0 de lo contrario. El primer bit de salida es siempre 1.

Ejemplo

Entrada:

Hi

Salida:

11011001011101

Explicación:

La cadena "Hola" tiene los códigos ASCII

72 105

que en bits son:

1001000 1101001

Y los indicadores de bits de transición:

11011001011101

Este es el código de golf. El conteo de bytes más bajo gana.

Casos de prueba

Caso de prueba 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Caso de prueba 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

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

##
11100101110010

¡Felicitaciones a Luis Mendo por la solución más corta con 9 bytes en MATL!


2
Caso de prueba sugerido ##( 0bit inicial; algunas respuestas actualmente fallan debido a eso)
Luis Mendo

44
¿Cómo es esto un duplicado del desafío de codificación de Manchester? ¿Me estoy perdiendo de algo?
Gastropner

2
El otro desafío dice convertir una secuencia de bits de entrada en una secuencia de salida de doble velocidad, con cada entrada '1' traducida a '01' y cada entrada '0' traducida a '10' . Así que no engaño en mi opinión. Si un gran número de personas vota el comentario de @ gastropner arriba, puedo dejar de engañar (o cualquier otro usuario con esa habilidad)
Luis Mendo

1
@Shaggy: Ambos casos de prueba incluyen un espacio, que tiene un solo conjunto de bits, y no el séptimo. Por lo tanto, no creo que la declaración del problema garantice que cada código ASCII tendrá exactamente 7 bits de longitud.
recursivo el

1
@SmileAndNod Pensándolo bien, creo que no necesitas manejar una cadena vacía.
justhalf

Respuestas:


4

MATL , 9 bytes

Hj7&B!hdg

Pruébalo en línea!

Explicación

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

1
Este es el más corto hasta ahora. +1. Es divertido tener un incorporado para diferencias consecutivas.
justhalf


4

Japt -P , 11 bytes

Aprovecha el hecho de que los espacios pueden ser forzados 0en JavaScript cuando se intenta realizar una operación matemática o, en este caso, bit a bit.

c_¤ù7Ãä^ i1

Pruébalo o ejecuta todos los casos de prueba

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

El 7 bits significa que si es 32 (para el carácter de espacio), lo sería 0100000. También el% character (37) sería0100101
justo el

Está funcionando ahora. +1
justo el

2

CJam , 21 bytes

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

Pruébalo en línea!

Explicación

Mostrando la pila con una entrada de muestra 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 ver si un bit es diferente del bit anterior, hacemos un vector (elemento-sabio) xor entre la matriz de bits y la matriz de bits sin el primer elemento. También eliminamos el último bit del resultado, porque siempre es el último bit de la matriz más larga sin cambios.


2

APL (Dyalog Unicode) , SBCS de 16 bytes

Programa completo Solicita una cadena desde stdin.

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

Pruébalo en línea!

 solicitud de entrada ("una cita en una consola")

11⎕DR¨ cambiar cada carácter a poco booleano D ata R ePresentation

1↓¨ soltar el primer bit de cada

ϵ nlist (aplanar)

2≠/ diferencia por pares

1, anteponer uno



2

Carbón , 25 bytes

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

Pruébalo en línea!El enlace es a la versión detallada del código. Explicación:

⭆θ◧⍘℅鲦⁷←

Convierta todos los caracteres a binario y rellene con una longitud de 7 y luego imprímalos, pero deje el cursor sobre el último dígito.

Wⅈ

Repita hasta que el cursor esté sobre el primer dígito.

←I﹪⍘KD²←01 ²

Calcule si los dígitos son diferentes y sobrescriba cada dígito con la diferencia.

1

Sobrescriba el primer dígito con 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]

Pruébalo en línea!

Una puñalada rápida.


Truco inteligente con a*128+ord(c)! Pero no es el reducey lambdatipo de costosa?
justhalf

1

Dardo , 213168 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);

Pruébalo en línea!

Esta verbosidad y falta de complementos fáciles de construir realmente está matando a este. Sin embargo, todavía logró sacar un trazador de líneas.

  • -45 bytes al no usar un trazador de líneas y usar un bucle 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)

Pruébalo en línea!

Espero poder mejorar esto pronto, siento que debe haber algunos puntos para mejorar, pero no puedo pensar en este momento



1

C (gcc (MinGW)), 90 bytes

Requiere un compilador que proporcione itoa().

n[9],b,c;f(char*s){for(b=*s<64;c=*s++;printf("%07s",itoa((c^c/2)&127,n,2)))c|=b<<7,b=c&1;}


1

Ruby -p , 50 bytes.

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

Pruébalo en línea!

Explicación

Primera línea, igual que la respuesta de Value Ink :

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

Segunda linea:

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.

En Rubí se puede utilizar la interpolación en los literales Regexp, por ejemplo /Hello #{name}/, y para las variables que comienzan con $o @se pueden omitir las llaves, así que si por ejemplo $&es "0"entonces el grawlixy /#$&$/convierte /0$/.


1

K (ngn / k) , 9 13 bytes

Solución:

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

Pruébalo en línea!

Explicación:

~=':,/(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 admitir cadenas que consisten solo en caracteres de 6 bits

Esto parece fallar para la entrada, #por ejemplo (la salida solo tiene 6 bits)
Luis Mendo

@streetster, ¿quieres publicar la versión fija?
justhalf

1

Emojicode , 263 bytes

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

Pruébelo en línea aquí.

Sin golf:

🏁 🍇  💭 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

Solución:

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

Explicación:

Desde que Python 3.8 introdujo expresiones de asignación (en lugar de las declaraciones de asignación estándar), he querido usarlas en una comprensión de lista que necesita recordar el último elemento. Esta no es la mejor manera de hacer esto, pero demuestra un método interesante de usar la expresión de asignación.

El código crea una función lambda que toma el argumento requerido, que es la cadena a convertir. Cuando se llama, la función procede de la siguiente manera. Cada carácter en a se convierte a su código de carácter al que se agrega 128 para tratar con caracteres de 6 bits (la representación binaria siempre será de 8 bits y podemos cortar el primer bit). Este número se convierte en binario y el encabezado (0x) y el 1 inicial de agregar 128 se cortan. Estas nuevas cadenas se unen en una cadena más grande.

Para cada carácter en esta nueva cadena (que contiene la representación concatenada de 7 bits del texto), se verifica si el carácter es el mismo que el anterior. ¿Qué pasa con el primer personaje? El primer carácter de resultado siempre debe ser "1", por lo que solo debemos asegurarnos de que lo que esté en la última variable de carácter no sea "1" ni "0". Hacemos esto reutilizando el parámetro original ahora que ya no lo estamos usando. Esto puede ser un problema si la cadena original era un solo "0" (un solo "1" simplemente funciona) pero lo ignoraremos.

Durante la comparación, el carácter anterior se evaluó primero, por lo que cuando usamos la expresión de asignación para establecer la variable de carácter anterior al carácter actual, no afecta la evaluación de las expresiones de comparación.

La comparación produce Verdadero o Falso, que también se puede usar como 1 o 0 respectivamente en Python, por lo que se usan para buscar un "1" o "0" en una cadena


Puede guardar algunos bytes utilizando literales de formato de cadena: 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}] ""}}

Pruébalo en línea!

Utiliza shift-by-one y exclusive-or para detectar transiciones. Lleva lsb del carácter actual al msb del siguiente carácter. Combina la salida para cada carácter uniendo la lista devuelta por lmap.

Utiliza lambdas con argumentos predeterminados para guardar bytes en la inicialización y comandos repetidos.

Depende en gran medida del orden de operación. Funciona para cadena vacía.


1

05AB1E (heredado) , 12 bytes

Çb7jð0:¥ÄJ1ì

Utiliza la versión heredada de 05AB1E, ya jque une implícitamente las cadenas, lo que requiere un explícito Jdespués dej de la nueva versión de 05AB1E.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

Ç             # 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)

Pruébalo en línea!

El mayor problema aquí es convertir booleanos (resultado del XOR) a '0' / '1'.





Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.