Transizione da stringa a bit


10

Compito

Data una stringa di input di uno o più caratteri ASCII i cui punti di codice sono compresi tra 0 e 128 (esclusivo), procedere come segue:

  1. Converti ogni carattere nel suo codice ASCII a 7 bit (se il codice ASCII è inferiore a 7 bit, inserisci zero bit iniziali)
  2. Concatena tutti i bit (questo si traduce in 7*nbit in cui nè il numero di caratteri)
  3. Per ogni bit in questo bitstream, stampa 1 se è diverso dal bit precedente e stampa 0 in caso contrario. Il primo bit di uscita è sempre 1.

Esempio

Ingresso:

Hi

Produzione:

11011001011101

Spiegazione:

La stringa "Hi" ha i codici ASCII

72 105

che in bit sono:

1001000 1101001

E gli indicatori dei bit di transizione:

11011001011101

Questo è il codice golf. Vince il conteggio dei byte più basso.

Casi test

Caso di prova 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Caso di prova 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

Caso di prova 3 (credito a Luis Mendo):

##
11100101110010

Congratulazioni a Luis Mendo per la soluzione più breve con 9 byte in MATL!


2
Caso di prova suggerito ##( 0bit iniziale; alcune risposte attualmente non riescono a causa di ciò)
Luis Mendo,

4
In che modo questo è un duplicato della sfida della codifica di Manchester? Mi sto perdendo qualcosa?
Gastropner,

2
L'altra sfida dice la conversione di un flusso di input di bit in un flusso di output a doppia velocità, con ogni input '1' tradotto in '01' e ogni input '0' tradotto in '10' . Quindi non ingannare secondo me. Se un gran numero di persone vota il commento di @ gastropner sopra posso annullare la duplicazione (o qualsiasi altro utente con quella capacità)
Luis Mendo,

1
@Shaggy: entrambi i casi di test includono uno spazio, che ha un solo bit impostato e non il settimo. Quindi non credo che l'istruzione del problema garantisca che ciascun codice ASCII avrà una lunghezza esatta di 7 bit.
ricorsivo il

1
@SmileAndNod Ripensandoci, penso che non sia necessario gestire una stringa vuota.
solo il

Risposte:


4

MATL , 9 byte

Hj7&B!hdg

Provalo online!

Spiegazione

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
Questo è il più breve finora. +1. È divertente avere un integrato per differenze consecutive.
solo il


4

Japt -P , 11 byte

Sfrutta il fatto che gli spazi possono essere forzati 0in JavaScript quando si tenta di eseguire un'operazione matematica o, in questo caso, bit a bit su di esso.

c_¤ù7Ãä^ i1

Provalo o esegui tutti i casi di test

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

Il 7 bit significa che se è 32 (per il carattere spazio), lo sarebbe 0100000. Anche il carattere% (37) sarebbe0100101
solo il

Sta lavorando adesso. +1
solo il

2

CJam , 21 byte

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

Provalo online!

Spiegazione

Mostra lo stack con un input di esempio di 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

Per vedere se un bit è diverso dal bit precedente, facciamo un vettore xor (saggio elemento) tra l'array di bit e l'array di bit senza il primo elemento. Rimuoviamo anche l'ultimo bit del risultato, perché è sempre invariato l'ultimo bit dell'array più lungo.


2

APL (Dyalog Unicode) , 16 byte SBCS

Programma completo. Richiede la stringa da stdin.

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

Provalo online!

 richiesta di input ("un preventivo in una console")

11⎕DR¨ cambiare ogni carattere al bit-booleana D ata R ePresentation

1↓¨ rilascia il primo bit da ciascuno

ϵ nlist (appiattisci)

2≠/ differenza a coppie

1, anteporre uno



2

Carbone , 25 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

⭆θ◧⍘℅鲦⁷←

Converti tutti i caratteri in binari e padli per una lunghezza di 7, quindi stampali, ma lascia il cursore sull'ultima cifra.

Wⅈ

Ripeti finché il cursore non si trova sulla prima cifra.

←I﹪⍘KD²←01 ²

Calcola se le cifre sono diverse e sovrascrivi ciascuna cifra con la differenza.

1

Sovrascrivi la prima cifra con a 1.





1

Python 2 , 104 byte

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]

Provalo online!

Una rapida pugnalata.


Trucco intelligente con a*128+ord(c)! Ma non è costoso reducee un lambdapo 'costoso?
solo il

1

Dardo , 213 168 byte

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 precedente

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

Provalo online!

Questa verbosità e la mancanza di semplici insiemi sta davvero uccidendo questo. Tuttavia, è riuscito comunque a tirare un liner.

  • -45 byte non usando un solo liner e usando un ciclo for


1

Kotlin , 182 byte

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)

Provalo online!

Spero di poterlo migliorare presto, sento che ci devono essere alcuni punti di miglioramento, ma non riesco a pensare in questo momento



1

C (gcc (MinGW)), 90 byte

Richiede un compilatore che fornisce 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

Rubino -p , 50 byte

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

Provalo online!

Spiegazione

Prima riga, uguale alla risposta di Value Ink :

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

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

In Ruby puoi usare l'interpolazione nei letterali Regexp, ad esempio /Hello #{name}/, e per le variabili che iniziano con $oppure @puoi omettere le parentesi graffe, quindi se ad esempio $&è "0"il grawlixy /#$&$/diventa /0$/.


1

K (ngn / k) , 9 13 byte

Soluzione:

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

Provalo online!

Spiegazione:

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

Appunti:

  • +4 byte per supportare stringhe costituite solo da caratteri a 6 bit

Questo sembra fallire per l'input, #ad esempio (l'output ha solo 6 bit)
Luis Mendo,

@streetster, vuoi pubblicare la versione fissa?
solo l'

1

Emojicode , 263 byte

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

Provalo online qui.

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 byte

Soluzione:

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

Spiegazione:

Da quando Python 3.8 ha introdotto le espressioni di assegnazione (piuttosto che le istruzioni di assegnazione standard), ho voluto usarle in una comprensione di elenco che deve ricordare l'ultimo elemento. Questo non è il modo migliore per farlo ma dimostra un metodo interessante di usare l'espressione di assegnazione.

Il codice crea una funzione lambda che accetta l'argomento richiesto che è la stringa da convertire. Quando viene chiamata, la funzione procede come segue. Ogni carattere in a viene convertito nel suo codice carattere a cui viene aggiunto 128 per gestire i caratteri a 6 bit (la rappresentazione binaria sarà sempre di 8 bit e possiamo tagliare il primo bit). Questo numero viene convertito in binario e l'intestazione (0x) e l'iniziale 1 dall'aggiunta di 128 vengono tagliati. Queste nuove stringhe vengono quindi unite in una stringa più grande.

Per ogni carattere di questa nuova stringa (che contiene la rappresentazione concatenata a 7 bit del testo), viene verificato se il carattere è lo stesso del carattere precedente. Cosa succede con il primo personaggio? Il carattere del primo risultato dovrebbe essere sempre "1", quindi dobbiamo solo assicurarci che tutto ciò che è nell'ultima variabile di carattere non sia né "1" né "0". Lo facciamo riutilizzando il parametro originale ora che non lo stiamo più usando. Questo potrebbe essere un problema se la stringa originale era un singolo "0" (un singolo "1" funziona), ma lo ignoreremo.

Durante il confronto, il carattere precedente è stato valutato per primo, quindi quando utilizziamo l'espressione di assegnazione per impostare la variabile di carattere precedente sul carattere corrente, ciò non influisce sulla valutazione delle espressioni di confronto.

Il confronto produce True o False che possono anche essere usati rispettivamente come 1 o 0 in Python, quindi sono usati per cercare "1" o "0" in una stringa


È possibile salvare alcuni byte utilizzando valori letterali in formato stringa: bin(ord(i)+128)[3:]->f"{ord(i):07b}"
movatica

1

Tcl , 215 167 140 byte

{{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}] ""}}

Provalo online!

Utilizza shift-by-one ed esclusivo-o per rilevare le transizioni. Porta lsb del carattere corrente a msb del carattere successivo. Combina l'output per ogni carattere unendo l'elenco restituito da lmap.

Utilizza lambdas con argomenti predefiniti per salvare byte all'inizializzazione e comandi ripetuti.

Si basa fortemente sull'ordine di funzionamento. Funziona con una stringa vuota.


1

05AB1E (legacy) , 12 byte

Çb7jð0:¥ÄJ1ì

Utilizza la versione legacy di 05AB1E, poiché junisce implicitamente le stringhe, il che richiede un esplicito Jdopo il jnella nuova versione di 05AB1E.

Provalo online o verifica tutti i casi di test .

Spiegazione:

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

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)

Provalo online!

Il problema più grande qui è convertire i booleani (risultato dello XOR) in '0' / '1'.





Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.