Übergang von Zeichenfolge zu Bit


10

Aufgabe

Gehen Sie bei einer Eingabezeichenfolge mit einem oder mehreren ASCII-Zeichen, deren Codepunkte zwischen 0 und 128 liegen (exklusiv), wie folgt vor:

  1. Konvertieren Sie jedes Zeichen in seinen 7-Bit-ASCII-Code (wenn der ASCII-Code weniger als 7 Bit beträgt, setzen Sie führende Nullbits)
  2. Verketten Sie alle Bits (dies führt zu 7*nBits, bei denen ndie Anzahl der Zeichen angegeben ist).
  3. Drucken Sie für jedes Bit in diesem Bitstrom 1, wenn es sich vom vorherigen Bit unterscheidet, und drucken Sie andernfalls 0. Das erste Ausgangsbit ist immer 1.

Beispiel

Eingang:

Hi

Ausgabe:

11011001011101

Erläuterung:

Die Zeichenfolge "Hi" hat die ASCII-Codes

72 105

welche in Bits sind:

1001000 1101001

Und die Übergangsbitindikatoren:

11011001011101

Das ist Code Golf. Die niedrigste Byteanzahl gewinnt.

Testfälle

Testfall 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Testfall 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

Testfall 3 (Dank an Luis Mendo):

##
11100101110010

Herzlichen Glückwunsch an Luis Mendo für die kürzeste Lösung mit 9 Bytes in MATL!


2
Vorgeschlagener Testfall ##(führendes 0Bit; einige Antworten scheitern derzeit daran)
Luis Mendo

4
Wie ist dies ein Duplikat der Manchester-Codierungsherausforderung? Vermisse ich etwas
Gastropner

2
Die andere Herausforderung besteht darin, einen Eingangsstrom von Bits in einen Ausgangsstrom mit doppelter Rate umzuwandeln, wobei jeder Eingang '1' in eine '01' und jeder Eingang '0' in eine '10' übersetzt wird . Also meiner Meinung nach nicht betrogen. Wenn eine große Anzahl von Leuten den obigen Kommentar von @ gastropner positiv bewertet, kann ich (oder jeden anderen Benutzer mit dieser Fähigkeit)
Luis Mendo

1
@Shaggy: Beide Testfälle enthalten ein Leerzeichen, für das nur ein einziges Bit gesetzt ist, und nicht das 7 .. Ich glaube also nicht, dass die Problemstellung garantiert, dass jeder ASCII-Code genau 7 Bit lang ist.
rekursiv

1
@ SmileAndNod Beim zweiten Gedanken denke ich, dass Sie nicht mit leeren Zeichenfolgen umgehen müssen.
halb

Antworten:


4

MATL , 9 Bytes

Hj7&B!hdg

Probieren Sie es online aus!

Erläuterung

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
Dies ist der bisher kürzeste. +1. Es macht Spaß, eine integrierte Funktion für aufeinanderfolgende Unterschiede zu haben.
halb


4

Japt -P , 11 Bytes

Nutzt die Tatsache aus, dass Leerzeichen 0in JavaScript erzwungen werden können, wenn versucht wird, eine mathematische oder in diesem Fall bitweise Operation daran durchzuführen.

c_¤ù7Ãä^ i1

Probieren Sie es aus oder führen Sie alle Testfälle aus

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

Das 7-Bit bedeutet, dass es 32 ist (für Leerzeichen) 0100000. Auch das% Zeichen (37) wäre0100101
halb

Es funktioniert jetzt. +1
halb

2

CJam , 21 Bytes

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

Probieren Sie es online aus!

Erläuterung

Anzeigen des Stapels mit einer Beispieleingabe von 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

Um festzustellen, ob sich ein Bit vom vorherigen Bit unterscheidet, führen wir einen Vektor (elementweise) xor zwischen dem Bitarray und dem Bitarray ohne das erste Element durch. Wir entfernen auch das letzte Bit des Ergebnisses, da es immer das letzte Bit des längeren Arrays unverändert ist.


2

APL (Dyalog Unicode) , 16 Byte SBCS

Volles Programm. Fordert zur Eingabe eines Strings von stdin auf.

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

Probieren Sie es online aus!

 Eingabeaufforderung ("ein Zitat in einer Konsole")

11⎕DR¨ ändern jedes Zeichen auf Bit-Boolesche D ata R ePresentation

1↓¨ Lass das erste Bit von jedem fallen

ϵ nlist (abflachen)

2≠/ paarweiser Unterschied

1, Stellen Sie eine Eins voran



2

Holzkohle , 25 Bytes

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

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Erläuterung:

⭆θ◧⍘℅鲦⁷←

Konvertieren Sie alle Zeichen in Binärzeichen und füllen Sie sie auf eine Länge von 7 auf. Drucken Sie sie dann aus, lassen Sie den Cursor jedoch über der letzten Ziffer.

Wⅈ

Wiederholen, bis sich der Cursor über der ersten Ziffer befindet.

←I﹪⍘KD²←01 ²

Berechnen Sie, ob die Ziffern unterschiedlich sind, und überschreiben Sie jede Ziffer mit der Differenz.

1

Überschreiben Sie die erste Ziffer mit a 1.






1

Dart , 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();}

Vorheriger Einzeiler

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

Probieren Sie es online aus!

Diese Ausführlichkeit und der Mangel an einfachen Einbauten bringt diesen wirklich um. Trotzdem gelang es mir, einen Einzeiler zu ziehen.

  • -45 Bytes, wenn kein Einzeiler und keine for-Schleife verwendet werden


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)

Probieren Sie es online aus!

Hoffentlich kann ich das bald verbessern. Ich habe das Gefühl, dass es einige Verbesserungsmöglichkeiten geben muss, aber ich kann momentan nicht denken



1

C (gcc (MinGW)), 90 Bytes

Erfordert die Bereitstellung eines Compilers 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}

Probieren Sie es online aus!

Erläuterung

Erste Zeile, genau wie die Antwort von Value Ink :

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

Zweite Reihe:

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 können Sie Interpolation in Regexp - Literale verwenden, zum Beispiel /Hello #{name}/, und für Variablen , die mit beginnen $oder @Sie können die geschweiften Klammern weglassen, also wenn zB $&ist "0"dann die grawlixy /#$&$/wird /0$/.


1

K (ngn / k) , 9 13 Bytes

Lösung:

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

Probieren Sie es online aus!

Erläuterung:

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

Anmerkungen:

  • +4 Bytes zur Unterstützung von Zeichenfolgen, die nur aus 6-Bit-Zeichen bestehen

Dies scheint zum #Beispiel für die Eingabe fehlzuschlagen (die Ausgabe hat nur 6 Bit)
Luis Mendo

@streetster, möchtest du die feste Version posten?
halb

1

Emojicode , 263 Bytes

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

Probieren Sie es hier online aus.

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

Lösung:

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

Erläuterung:

Seit Python 3.8 Zuweisungsausdrücke (anstelle der Standardzuweisungsanweisungen) eingeführt hat, wollte ich sie in einem Listenverständnis verwenden, das sich an das letzte Element erinnern muss. Dies ist nicht der beste Weg, zeigt jedoch eine interessante Methode zur Verwendung des Zuweisungsausdrucks.

Der Code erstellt eine Lambda-Funktion, die das erforderliche Argument verwendet, das die zu konvertierende Zeichenfolge ist. Beim Aufruf läuft die Funktion wie folgt ab. Jedes Zeichen in a wird in seinen Zeichencode konvertiert, dem 128 für den Umgang mit 6-Bit-Zeichen hinzugefügt wird (die binäre Darstellung beträgt immer 8 Bit, und wir können das erste Bit abhacken). Diese Zahl wird in eine Binärzahl umgewandelt und der Header (0x) und die anfängliche 1 aus dem Hinzufügen von 128 werden abgeschnitten. Diese neuen Zeichenfolgen werden dann zu einer größeren Zeichenfolge zusammengefügt.

Für jedes Zeichen in dieser neuen Zeichenfolge (die die verkettete 7-Bit-Darstellung des Textes enthält) wird geprüft, ob das Zeichen mit dem vorherigen Zeichen identisch ist. Was passiert mit dem ersten Charakter? Das erste Ergebniszeichen sollte immer "1" sein, daher müssen wir nur sicherstellen, dass alles, was in der letzten Zeichenvariablen enthalten ist, weder "1" noch "0" ist. Wir tun dies, indem wir den ursprünglichen Parameter jetzt wiederverwenden, da wir ihn nicht mehr verwenden. Dies kann ein Problem sein, wenn die ursprüngliche Zeichenfolge eine einzelne "0" war (eine einzelne "1" funktioniert einfach), aber wir werden das ignorieren.

Während des Vergleichs wurde das vorherige Zeichen zuerst ausgewertet. Wenn wir also den Zuweisungsausdruck verwenden, um die vorherige Zeichenvariable auf das aktuelle Zeichen zu setzen, hat dies keinen Einfluss auf die Auswertung der Vergleichsausdrücke.

Der Vergleich ergibt entweder True oder False, die in Python auch als 1 oder 0 verwendet werden können. Sie werden also verwendet, um entweder eine "1" oder "0" in einer Zeichenfolge nachzuschlagen


Sie können einige Bytes speichern, indem Sie Literale im Zeichenfolgenformat verwenden: 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}] ""}}

Probieren Sie es online aus!

Verwendet Shift-by-One und Exclusive-Or, um Übergänge zu erkennen. Überträgt lsb des aktuellen Zeichens zu msb des nächsten Zeichens. Kombiniert die Ausgabe für jedes Zeichen, indem die von lmap zurückgegebene Liste verknüpft wird.

Verwendet Lambdas mit Standardargumenten, um Bytes bei der Initialisierung und wiederholten Befehlen zu speichern.

Verlässt sich stark auf die Reihenfolge des Betriebs. Funktioniert für leere Zeichenfolgen.


1

05AB1E (Legacy) , 12 Bytes

Çb7jð0:¥ÄJ1ì

Verwendet die Legacy-Version von 05AB1E, da jdie Zeichenfolgen implizit miteinander verbunden werden, was in der neuen Version von 05AB1E ein explizites JNach jerfordert.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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

Probieren Sie es online aus!

Das größte Problem hierbei ist die Konvertierung von Booleschen Werten (Ergebnis des XOR) in '0' / '1'.





Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.