Le codage Manchester est un protocole de télécommunications utilisé dans les communications radio qui garantit des transitions de bits à un intervalle régulier afin qu'un récepteur puisse récupérer la fréquence d'horloge à partir des données elles-mêmes. Il double le débit binaire, mais est bon marché et simple à mettre en œuvre. Il est largement utilisé par les opérateurs de radio amateur.
Le concept est très simple: au niveau matériel, l'horloge et les lignes de données sont simplement XOR ensemble. Dans le logiciel, cela est décrit comme convertissant un flux d'entrée de bits en un flux de sortie à double débit, chaque entrée «1» étant traduite en «01» et chaque entrée «0» traduite en «10».
C'est un problème facile, mais ouvert à de nombreuses implémentations en raison de sa nature bitstream. Autrement dit, le codage est conceptuellement un processus bit par bit au lieu d'un processus octet par octet. Nous sommes donc tous d'accord sur l'endianité, les bits les moins significatifs de l'entrée deviennent l'octet le moins significatif de la sortie.
Le temps du golf! Écrivez une fonction qui, étant donné un tableau d'octets de longueur arbitraire, retourne un tableau de ce gestionnaire de données codé.
L'entrée et la sortie doivent être considérées comme peu endiennes, l'octet le moins significatif en premier et le BIT le moins significatif en premier dans le flux binaire.
Dessin de flux binaire ASCII :
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
Exemples :
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]
Règles :
- La solution ne nécessite qu'un algorithme pour convertir l'entrée en sortie.
- L'acquisition d'entrée et de sortie d'impression NE fait PAS partie de la solution, mais peut être incluse. Nous vous encourageons à fournir votre code de test / d'impression s'il n'est pas inclus dans votre solution.
- L'entrée est un tableau d'octets de 8 bits (quoi que cela puisse signifier dans la langue de votre choix), PAS une chaîne de texte. Vous pouvez utiliser des chaînes comme format de stockage si cela vous convient dans votre langue, mais les caractères non imprimables (c'est-à-dire 0xFF) doivent être pris en charge. L'entrée peut également prendre une longueur si nécessaire.
La mémoire de sortie doit être allouée par votre routine, non fournie.modifier: exigence inutile- La sortie est également un tableau d'octets de 8 bits et une longueur si nécessaire.
- Doit prendre en charge au moins 16 Ko d'entrée
- Les performances ne doivent pas être trop horribles: <10s pour 16 Ko
- Octet le moins significatif en premier en mémoire.
Défi du canal latéral :
- Défiez la réponse d'un autre utilisateur en prouvant que votre code est plus rapide, plus efficace en mémoire ou produit un binaire plus petit!
Réponses:
GolfScript 28 caractères
Version équivalente sans optimisation obscurcissante:
Le code accepte l'entrée comme un tableau d'entiers et renvoie idem.
Pour chaque nombre dans le tableau, le nombre est converti en forme de tableau en base 2, il est ensuite reconverti en un nombre comme s'il s'agissait de la base 4, ce qui a pour effet d'espacer les bits avec un 0 entre chacun. 43691 est ensuite soustrait du nombre, et le résultat est binaire inversé, ce qui équivaut à soustraire le nombre de 43690 (43690 = 0b1010101010101010). Le nombre est ensuite divisé en deux parties en le convertissant en un tableau de base 256, le tableau est décomposé et l'ordre des deux nombres résultants est inversé.
Exemple d'entrée:
Exemple de sortie:
la source
{2{base}:|~4|43691-~256|~p p}%
c - 224 caractères
Je crois que cela est fonctionnel, y compris l'allocation de mémoire requise depuis abandonné.
La partie de travail du code est une boucle sur les bits de chaque caractère, notant que ((bit + 1) exclusif ou 3) est la paire de bits de sortie, et appliquant beaucoup de logique de décalage et de masquage pour que tout soit aligné.
Comme c'est l'habitude de c, cela fonctionne sur les données sous forme de caractères. L'échafaudage de test n'acceptera pas 0 octet (car c les traite comme une fin de chaîne), mais le code de travail n'a pas une telle limitation.
Il pourrait être joué un peu plus en copiant le travail de conversion d'octets en ligne.
Test (avec échafaudage de test amélioré):
Commenté, moins dépendant de la machine et avec échafaudage de test
la source
J, 36
Aperçu de l'explication (voir le vocabulaire J pour référence):
,@:(3 :'...'"0)
applique le ... à chaque "octet" d'entrée comme y, résultant en deux octets (entiers) chacun. Le résultat est aplati par,
.y#:~8#2
est équivalent2 2 2 2 2 2 2 2 #: y
ou vecteur des 8 chiffres de base 2 les moins significatifs de y.4|.
échange les 4 bits avant et arrière en tournant de 4 positions.(,.~-.)
est équivalent3 :'(-. y) ,. y'
ou non à l'argument «assemblé» à l'argument (prenant la forme 8 2).#.2 8$,
aplatit le résultat en donnant le train de bits, remodèle à 2 rangées de 8 et convertit à partir de la base 2.Exemple d'utilisation (J, interactif):
Informations de vitesse (J, interactif):
Le temps moyen pour 16 Ko est un peu moins de 0,25 s, Intel Core Duo 1,83 GHz ou similaire.
la source
Haskell, 76 caractères
Essais:
Les performances sont bien conformes aux spécifications. à 1 Mo en ~ 1,2 s sur mon portable ancien. Il souffre parce que l'entrée est convertie vers et depuis une liste, plutôt traitée comme un
ByteArray
.La source, 2040-Manchester.hs , inclut le code, les tests et la fonction principale d'un filtre de ligne de commande.
la source
OCaml + Batteries,
138117 caractèresTests:
Avec
Les résultats sont:
Comme référence, avec:
Je reçois:
sur mon MacBook.
la source
Python, 87 caractères
M
est la fonction demandée dans le problème. Il appelleN
chaque nybble et regroupe tout en une liste.génère
la source
APL (Dyalog Extended) , 22 octets
Essayez-le en ligne!
Port de la réponse GolfScript.
la source
C, 164 octets
Prend une série d'octets hexadécimaux et convertit en flux binaire manchester.
Tester:
Production:
Générateur de jeu de données de test de 16 Ko:
test_data.c:
Contre-la-montre de base 1.6G i5dual:
la source
PHP, 156 octets
Compte tenu de l'entrée
[0, 1, 2, 3, 4, 5]
, il renvoie:Il code 16 Ko de données en 0,015 seconde et 1 Mo de données en environ 0,9 seconde.
Le code non golfé, une autre implémentation (plus longue et environ deux fois plus lente) et les cas de test peuvent être trouvés sur ma page de solutions de golf de code sur Github.
la source