Манчестерское кодирование - это телекоммуникационный протокол, используемый в радиосвязи, который гарантирует битовые переходы с регулярным интервалом, чтобы приемник мог восстановить тактовую частоту из самих данных. Он удваивает битрейт, но дешев и прост в реализации. Широко используется радиолюбителями.
Концепция очень проста: на аппаратном уровне часы и линии данных просто объединяются в XOR. В программном обеспечении это изображается как преобразование входного потока битов в выходной поток с двойной скоростью, причем каждый вход «1» транслируется в «01», а каждый вход «0» транслируется в «10».
Это простая проблема, но она открыта для многих реализаций из-за своей природы потока битов. То есть кодирование концептуально является побитовым процессом, а не побитовым процессом. Таким образом, мы все согласны с порядком байтов, младшие значащие биты входных данных становятся наименее значимыми байтами выходных данных.
Время игры в гольф! Напишите функцию, которая, учитывая массив байтов произвольной длины, возвращает массив этих манчестерских данных.
Ввод и вывод должны рассматриваться как младшие байты, младший значащий байт первым и младший значащий бит в битовом потоке.
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
Примеры :
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]
правила :
- Решение требует только алгоритм для преобразования ввода в вывод.
- Получение ввода и вывод на печать НЕ являются обязательной частью решения, но могут быть включены. Вам предлагается предоставить свой тестовый / распечатанный код, если он не включен в ваше решение.
- Входные данные - это массив 8-битных байтов (что бы это ни значило на выбранном вами языке), а НЕ текстовая строка. Вы можете использовать строки в качестве формата хранения, если это удобно на вашем языке, но должны поддерживаться непечатаемые символы (например, 0xFF). Ввод может также занять длину при необходимости.
Память для вывода должна быть выделена вашей программой, а не предоставлена.редактировать: ненужное требование- Вывод также представляет собой массив из 8-битных байтов и длины при необходимости.
- Должен поддерживать не менее 16 КБ ввода
- Производительность не должна быть слишком ужасной: <10 с для 16 КБ
- Наименее значимый байт первым в памяти.
Задача побочного канала :
- Испытайте ответ другого пользователя, доказав, что ваш код быстрее, эффективнее использует память или создает меньший двоичный файл!
Ответы:
GolfScript 28 символов
Эквивалентная версия без запутывающей оптимизации:
Код принимает входные данные как массив целых чисел и возвращает то же самое.
Для каждого числа в массиве число преобразуется в форму массива с основанием 2, затем оно преобразуется обратно в число, как если бы оно было основанием 4, это дает эффект разнесения битов с 0 между ними. 43691 затем вычитается из числа, и результат двоично инвертируется, это эквивалентно вычитанию числа из 43690 (43690 = 0b1010101010101010). Затем число делится на две части путем преобразования его в базовый массив 256, массив разлагается и порядок двух результирующих чисел инвертируется.
Пример ввода:
Пример вывода:
источник
{2{base}:|~4|43691-~256|~p p}%
с - 224 символа
Я считаю, что это функционально, в том числе распределение требований к памяти, поскольку упал.
Рабочая часть кода представляет собой цикл над битами каждого символа, отмечая, что ((бит + 1) исключительный-или 3) является выходной парой битов, и применяя много логики сдвига и маскирования, чтобы все выстраивалось в линию.
Как обычно, c работает с данными как с символами. Тестовый скаффолд не будет принимать 0 байтов (потому что c рассматривает их как завершение строки), но рабочий код не имеет такого ограничения.
Это может быть немного больше, если скопировать байтовую конвертацию.
Тестовый прогон (с улучшенным тестовым каркасом):
Комментируется, меньше зависит от машины, и с тестовым помостом
источник
J, 36
Схема объяснения (см. J Словарь ):
,@:(3 :'...'"0)
применяет ... к каждому входному "байту" как y, в результате чего получается два байта (целых числа) каждый. Результат сглажен,
.y#:~8#2
является эквивалентом2 2 2 2 2 2 2 2 #: y
или вектором 8 младших значащих цифр основания-2 у.4|.
меняет местами передние и задние 4 бита, поворачивая их на 4 позиции.(,.~-.)
эквивалентно3 :'(-. y) ,. y'
или нет аргумента, «сшитого» с аргументом (принимает форму 8 2).#.2 8$,
выравнивает результат, давая поток битов, преобразует в 2 строки по 8 и преобразует из базы 2.Пример использования (J, интерактив):
Информация о скорости (J, интерактивная):
Среднее время для 16 КБ чуть меньше 0,25 с, Intel Core Duo 1,83 ГГц или аналогичный.
источник
Haskell, 76 символов
Тестовые прогоны:
Производительность хорошо в пределах спец. на 1MB в ~ 1.2s на моем старом ноутбуке. Он страдает, потому что входные данные преобразуются в и из списка, а не обрабатываются как
ByteArray
.Исходный код 2040-Manchester.hs содержит код, тесты и основную функцию для фильтра командной строки.
источник
OCaml + Батареи,
138117 знаковтесты:
С
Результаты:
В качестве ориентира, с:
Я получил:
на моем MacBook.
источник
Питон, 87 символов
M
является функцией, запрошенной в проблеме. Он вызываетN
каждый кусок и объединяет все обратно в список.генерирует
источник
APL (Dyalog Extended) , 22 байта
Попробуйте онлайн!
Порт ответа GolfScript.
источник
C 164 байта
Принимает серию шестнадцатеричных байтов и преобразует в двоичный поток Манчестера.
Тестовое задание:
Выход:
16kb генератор тестовых данных:
test_data.c:
1.6G i5dual основное время:
источник
PHP, 156 байт
Учитывая вход
[0, 1, 2, 3, 4, 5]
, он возвращает:Он кодирует 16 КиБ данных за 0,015 секунды и 1 МиБ данных за 0,9 секунды.
Код ungolfed, другая реализация (длиннее и примерно в два раза медленнее) и контрольные примеры можно найти на моей странице решений для code-golf на Github.
источник