Kodowanie Manchester jest protokołem telekomunikacyjnym stosowanym w komunikacji radiowej, który gwarantuje przejścia bitów w regularnych odstępach czasu, dzięki czemu odbiornik może odzyskać częstotliwość zegara z samych danych. Podwaja przepływność, ale jest tani i prosty do wdrożenia. Jest szeroko stosowany przez amatorskich operatorów radiowych.
Pomysł jest bardzo prosty: na poziomie sprzętowym zegar i linie danych są po prostu XOR razem. W oprogramowaniu jest to przedstawiane jako przekształcanie strumienia wejściowego bitów w strumień wyjściowy o podwójnej szybkości, z każdym wejściowym „1” przetłumaczonym na „01” i każdym wejściowym „0” przetłumaczonym na „10”.
Jest to prosty problem, ale otwarty na wiele implementacji ze względu na swój charakter strumienia bitów. Oznacza to, że kodowanie jest koncepcyjnie procesem krok po kroku zamiast procesu bajt po bajcie. Wszyscy zgadzamy się co do endianowości, najmniej znaczące bity wejściowe stają się najmniej znaczącym bajtem wyjściowym.
Czas na golfa! Napisz funkcję, która, biorąc pod uwagę dowolną długość tablicy bajtów, zwraca tablicę danych zakodowanych w Manchester.
Wejścia i wyjścia należy traktować jako little-endian, najpierw najmniej znaczący bajt, a najmniej znaczący BIT pierwszy w strumieniu bitów.
Rysunek strumienia bitów 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
Przykłady :
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]
Zasady :
- Rozwiązanie wymaga jedynie algorytmu do konwersji danych wejściowych na dane wyjściowe.
- Pozyskiwanie danych wejściowych i wyjściowych NIE jest wymaganą częścią rozwiązania, ale może zostać uwzględnione. Zachęcamy do podania kodu testowego / drukowanego, jeśli nie jest uwzględniony w rozwiązaniu.
- Dane wejściowe to tablica 8-bitowych bajtów (cokolwiek to może znaczyć w wybranym języku), a NIE ciąg tekstowy. Możesz użyć ciągów jako formatu pamięci, jeśli jest to wygodne w twoim języku, ale znaki niedrukowalne (tj. 0xFF) muszą być obsługiwane. W razie potrzeby dane wejściowe mogą również trwać długo.
Pamięć wyjściowa musi być przydzielona przez twoją procedurę, a nie zapewniona.edycja: niepotrzebne wymagania- Dane wyjściowe to także tablica 8-bitowych bajtów i długość, jeśli to konieczne.
- Musi obsługiwać co najmniej 16 KB wejścia
- Wydajność nie może być zbyt okropna: <10 s dla 16 KB
- Najmniej znaczący bajt jako pierwszy w pamięci.
Wyzwanie w kanale bocznym :
- Zmierz się z odpowiedzią innego użytkownika, udowadniając, że Twój kod jest szybszy, bardziej wydajny pod względem pamięci lub tworzy mniejszy plik binarny!
Odpowiedzi:
GolfScript 28 znaków
Wersja równoważna bez zaciemniającej optymalizacji:
Kod akceptuje dane wejściowe jako tablicę liczb całkowitych i zwraca to samo.
Dla każdej liczby w tablicy liczba jest konwertowana na postać macierzy podstawy 2, a następnie jest konwertowana z powrotem na liczbę, tak jakby to była podstawa 4, co powoduje rozstawianie bitów z 0 pomiędzy nimi. 43691 jest następnie odejmowane od liczby, a wynik jest odwracany binarnie, co jest równoważne odejmowaniu liczby od 43690 (43690 = 0b1010101010101010). Liczba jest następnie dzielona na dwie części przez przekształcenie jej w podstawową tablicę 256, tablica jest rozkładana i kolejność dwóch wynikowych liczb jest odwracana.
Przykładowe dane wejściowe:
Przykładowe dane wyjściowe:
źródło
{2{base}:|~4|43691-~256|~p p}%
c - 224 znaki
Uważam, że jest to funkcjonalne, w tym alokacja zapotrzebowania na pamięć od momentu jego utraty.
Działającą częścią kodu jest pętla nad bitami każdego znaku, zauważając, że ((bit + 1) wyłączny-lub 3) jest parą bitów wyjściowych i stosuje wiele logiki przesunięcia i maskowania, aby wszystko wyrównać.
Jak to zwykle bywa, działa on na danych jako znakach. Testowe rusztowanie nie przyjmuje 0 bajtów (ponieważ c traktuje je jako zakończenie łańcucha), ale działający kod nie ma takich ograniczeń.
Może być nieco bardziej golfa, kopiując wbudowaną konwersję bajtów.
Uruchomienie testowe (z ulepszonym rusztowaniem testowym):
Komentowany, mniej zależny od maszyny i z rusztowaniem testowym
źródło
J, 36
Zarys wyjaśnienia (zob. J Słownictwo w celu odniesienia):
,@:(3 :'...'"0)
stosuje ... do każdego wejściowego „bajtu” jako y, co daje dwa bajty (liczby całkowite) każdy. Wynik jest spłaszczony o,
.y#:~8#2
jest równoważne2 2 2 2 2 2 2 2 #: y
lub wektorze z 8 najmniej znaczących cyfr podstawowych 2 y.4|.
zamienia przednie i tylne 4 bity, obracając o 4 pozycje.(,.~-.)
jest równoważne3 :'(-. y) ,. y'
argumentowi „zszytemu” z argumentem (przybierając kształt 8 2) lub nie.#.2 8$,
spłaszcza wynik, dając strumień bitów, przekształca go w 2 rzędy po 8 i konwertuje z podstawy 2.Przykładowe użycie (J, interaktywne):
Informacje o prędkości (J, interaktywne):
Średni czas dla 16 kb to niecałe 0,25 s, Intel Core Duo 1,83 Ghz lub podobny.
źródło
Haskell, 76 znaków
Przebiegi testowe:
Wydajność mieści się w zakresie specyfikacji. przy 1 MB w ~ 1,2 s na moim starym laptopie. Cierpi, ponieważ dane wejściowe są konwertowane na listę iz listy, a następnie przetwarzane jako
ByteArray
.Źródło, 2040-Manchester.hs , zawiera kod, testy i główną funkcję filtru wiersza poleceń.
źródło
OCaml + Baterie,
138117 znakówTesty:
Z
Wyniki są następujące:
Jako punkt odniesienia z:
Dostaję:
na moim MacBooku.
źródło
Python, 87 znaków
M
jest funkcją wymaganą w problemie. WzywaN
do każdego wątku i dzieli wszystko z powrotem na listę.generuje
źródło
APL (Dyalog Extended) , 22 bajty
Wypróbuj online!
Port odpowiedzi GolfScript.
źródło
C, 164 bajty
Pobiera szereg bajtów szesnastkowych i konwertuje na strumień binarny Manchester.
Test:
Wynik:
Generator zestawu danych testowych 16kb:
test_data.c:
1.6G i5dual czas próbny rdzenia:
źródło
PHP, 156 bajtów
Biorąc pod uwagę dane wejściowe
[0, 1, 2, 3, 4, 5]
, zwraca:Koduje 16 KiB danych w 0,015 sekundy i 1 MiB danych w około 0,9 sekundy.
Niegolfowany kod, kolejna implementacja (dłuższa i około dwukrotnie wolniejsza) oraz przypadki testowe można znaleźć na mojej stronie rozwiązań do gry w golfa na Githubie.
źródło