Die Manchester-Codierung ist ein Telekommunikationsprotokoll, das in der Funkkommunikation verwendet wird und in regelmäßigen Abständen Bitübergänge garantiert, damit ein Empfänger die Taktrate aus den Daten selbst wiederherstellen kann. Es verdoppelt die Bitrate, ist aber billig und einfach zu implementieren. Es wird häufig von Amateurfunkern eingesetzt.
Das Konzept ist sehr einfach: Auf Hardware-Ebene werden die Takt- und Datenleitungen einfach XOR-verknüpft. In der Software wird dies so dargestellt, dass ein Eingabestrom von Bits in einen Ausgabestrom mit doppelter Rate umgewandelt wird, wobei jede Eingabe "1" in eine "01" und jede Eingabe "0" in eine "10" übersetzt wird.
Dies ist ein einfaches Problem, das aufgrund seines Bitstream-Charakters jedoch für viele Implementierungen offen ist. Das heißt, die Codierung ist konzeptionell ein bitweiser Prozess anstelle eines byteweisen Prozesses. Wir sind uns also alle einig, dass die niedrigstwertigen Bits der Eingabe das niedrigstwertige Byte der Ausgabe sind.
Zeit zum Golfen! Schreiben Sie eine Funktion, die bei einem Array mit beliebiger Länge von Bytes ein Array der nach Manchester codierten Daten zurückgibt.
Eingabe und Ausgabe sollten als Little-Endian, niedrigstwertiges Byte zuerst und niedrigstwertiges BIT zuerst im Bitstrom betrachtet werden.
ASCII - Bitstrom Zeichnung :
bit # 5 4 3 2 1 0 5 4 3 2 1 0
IN ------- 1 0 1 0 1 1 ---> [manchester encoder] --- 01 10 01 10 01 01 ----> OUT
Beispiele :
Example 1 (hex):
LSB MSB <-- least sig BYTE first
IN : [0x10, 0x02]
OUT: [0xAA, 0xA9, 0xA6, 0xAA]
Example 1 (binary):
msb lsb msb lsb <-- translated hex, so msb first
BIN: [00010000, 00000010] <-- least sig NIBBLE...
BIN: [10101010, 10101001, 10100110, 10101010] <-- becomes least sig BYTE
LSB MSB
Example 2
IN : [0xFF, 0x00, 0xAA, 0x55]
OUT: [0x55, 0x55, 0xAA, 0xAA, 0x66, 0x66, 0x99, 0x99]
Example 3
IN : [0x12, 0x34, 0x56, 0x78, 0x90]
OUT: [0xA6, 0xA9, 0x9A, 0xA5, 0x96, 0x99, 0x6A, 0x95, 0xAA, 0x69]
Example 4
IN : [0x01, 0x02, 0x03, 0xF1, 0xF2, 0xF3]
OUT: [0xA9, 0xAA, 0xA6, 0xAA, 0xA5, 0xAA, 0xA9, 0x55, 0xA6, 0x55, 0xA5, 0x55]
Regeln :
- Die Lösung erfordert nur einen Algorithmus, um die Eingabe in die Ausgabe umzuwandeln.
- Erfassen von Eingaben und Drucken von Ausgaben sind KEIN erforderlicher Teil der Lösung, können jedoch enthalten sein. Sie werden aufgefordert, Ihren Test- / Druckcode anzugeben, wenn dieser nicht in Ihrer Lösung enthalten ist.
- Die Eingabe ist ein Array von 8-Bit-Bytes (was auch immer dies in der Sprache Ihrer Wahl bedeuten mag), KEINE Textzeichenfolge. Sie können Zeichenfolgen als Speicherformat verwenden, wenn dies in Ihrer Sprache zweckmäßig ist. Nicht druckbare Zeichen (z. B. 0xFF) müssen jedoch unterstützt werden. Bei Bedarf kann die Eingabe auch eine Länge haben.
Der Speicher für die Ausgabe muss von Ihrer Routine zugewiesen werden und wird nicht bereitgestellt.edit: unnötige anforderung- Die Ausgabe erfolgt ebenfalls in einem Array von 8-Bit-Bytes und bei Bedarf in einer Länge.
- Müssen mindestens 16KB Eingang unterstützen
- Die Leistung darf nicht zu schlecht sein: <10s für 16KB
- Das niedrigstwertige Byte zuerst im Speicher.
Seitenkanal-Herausforderung :
- Fordern Sie die Antwort eines anderen Benutzers heraus, indem Sie beweisen, dass Ihr Code schneller und speichereffizienter ist oder eine kleinere Binärdatei erzeugt!
Antworten:
GolfScript 28 Zeichen
Äquivalente Version ohne verschleierte Optimierung:
Der Code akzeptiert Eingaben als Array von Ganzzahlen und gibt dasselbe zurück.
Für jede Zahl in dem Array wird die Zahl in die Matrixform zur Basis 2 konvertiert, dann wird sie zurück in eine Zahl konvertiert, als ob es die Basis 4 wäre. Dies hat den Effekt, dass die Bits mit einer 0 dazwischen beabstandet werden. 43691 wird dann von der Zahl subtrahiert, und das Ergebnis wird binär invertiert. Dies entspricht dem Subtrahieren der Zahl von 43690 (43690 = 0b10101010101010). Die Zahl wird dann in zwei Teile geteilt, indem sie in ein Basis-256-Array umgewandelt wird, das Array wird zerlegt und die Reihenfolge der beiden resultierenden Zahlen wird invertiert.
Beispiel Eingabe:
Beispielausgabe:
quelle
{2{base}:|~4|43691-~256|~p p}%
c - 224 Zeichen
Ich glaube, dass dies funktioniert, einschließlich der Zuordnung des Speicherbedarfs, der seither entfällt.
Der funktionierende Teil des Codes ist eine Schleife über die Bits jedes Zeichens, wobei zu beachten ist, dass ((bit + 1) exclusive-or 3) das Ausgangsbitpaar ist, und viel Verschiebungs- und Maskierungslogik angewendet wird, um alles in eine Linie zu bringen.
Wie bei c üblich, werden die Daten als Zeichen verarbeitet. Das Testgerüst akzeptiert keine 0 Bytes (weil c sie als String-Endung behandelt), aber der Arbeitscode unterliegt keiner solchen Einschränkung.
Wenn Sie die Byte-Konvertierungsarbeit inline kopieren, wird möglicherweise etwas mehr Golf gespielt.
Testlauf (mit verbessertem Testgerüst):
Kommentiert, weniger maschinenabhängig und mit Testgerüst
quelle
J, 36
Erklärung (Siehe J Vokabular als Referenz):
,@:(3 :'...'"0)
Wendet das ... auf jedes Eingabe- "Byte" als y an, was jeweils zwei Bytes (ganze Zahlen) ergibt. Das Ergebnis wird durch abgeflacht,
.y#:~8#2
ist äquivalent zu2 2 2 2 2 2 2 2 #: y
oder Vektor der 8 niedrigstwertigen Basis-2-Stellen von y.4|.
Vertauscht die vorderen und hinteren 4 Bits durch Drehen um 4 Positionen.(,.~-.)
entspricht3 :'(-. y) ,. y'
oder nicht dem Argument, das mit dem Argument „verbunden“ ist (nimmt die Form 8 2 an).#.2 8$,
Verflacht das Ergebnis mit dem Bitstream, formt sich in 2 8er-Zeilen um und konvertiert von Basis 2.Anwendungsbeispiel (J, interaktiv):
Geschwindigkeitsinformationen (J, interaktiv):
Die durchschnittliche Zeit für 16 KB beträgt knapp 0,25 s, Intel Core Duo 1,83 GHz oder ähnliches.
quelle
Haskell, 76 Zeichen
Testläufe:
Die Leistung entspricht den Spezifikationen. bei 1 MB in ~ 1,2 s auf meinem alten Laptop. Es leidet, weil die Eingabe in und aus einer Liste konvertiert und dann als eine verarbeitet wird
ByteArray
.Die Quelle 2040-Manchester.hs enthält den Code, die Tests und die Hauptfunktion für einen Befehlszeilenfilter.
quelle
OCaml + Batterien,
138117 ZeichenTests:
Mit
Die Ergebnisse sind:
Als Benchmark mit:
Ich bekomme:
auf meinem MacBook.
quelle
Python, 87 Zeichen
M
ist die im Problem angeforderte Funktion. Es ruftN
nach jedem Nybble auf und fügt alles wieder in eine Liste ein.erzeugt
quelle
APL (Dyalog Extended) , 22 Byte
Probieren Sie es online!
Port der GolfScript-Antwort.
quelle
C 164 Bytes
Nimmt eine Reihe von hexadezimalen Bytes auf und konvertiert sie in einen Manchester-Binärdatenstrom.
Prüfung:
Ausgabe:
16kb Testdatensatz Generator:
test_data.c:
1.6G i5dual Core Zeitfahren:
quelle
PHP, 156 Bytes
Bei der Eingabe
[0, 1, 2, 3, 4, 5]
wird Folgendes zurückgegeben:Es codiert 16 KB Daten in 0,015 Sekunden und 1 MB Daten in etwa 0,9 Sekunden.
Den ungolfed Code, eine weitere Implementierung (länger und ungefähr zweimal langsamer) und die Testfälle finden Sie auf meiner Code-Golf-Lösungsseite bei Github.
quelle