Вступление
В этом задании вы будете решать диагональные преобразования Барроуза-Уилера. Вот общий обзор диагонального преобразования Барроуза-Уилера. Для кодирования сообщения сначала необходимо убедиться, что оно нечетной длины (т. Е. 5, 7, 9 и т. Д.). Затем вы делаете сетку, с n
помощью n
, где n
длина сообщения. Первая строка - это оригинальное сообщение. Каждая строка после этого является строкой над ней, но смещается на 1 символ влево, а первый символ перемещается назад. Например:
Hello World
ello WorldH
llo WorldHe
lo WorldHel
o WorldHell
WorldHello
WorldHello
orldHello W
rldHello Wo
ldHello Wor
dHello Worl
Затем вы берете каждую букву от диагонали NW до SE и помещаете ее в новую строку:
Hello World H
ello WorldH l
llo WorldHe o
lo WorldHel W
o WorldHell r
WorldHello d
WorldHello e
orldHello W l
rldHello Wo (space)
ldHello Wor o
dHello Worl l
Ваше кодированное сообщение HloWrdel ol
. Для декодирования сначала возьмите длину закодированного сообщения, добавьте 1 и разделите на 2. Позволяет позвонить по этому номеру x
. Теперь, когда мы знаем x
, начиная с первой буквы, каждая буква идет x
после последней и повторяется. Например:
H l o W r d e l o l
1
Then...
H l o W r d e l o l
1 2
And again...
H l o W r d e l o l
1 3 2
Until you get...
H l o W r d e l o l
1 3 5 7 9 11 2 4 6 8 10
Теперь просто переставьте буквы в правильном порядке, чтобы получить Hello World
!
Вызов
Ваша задача - написать две программы, функции или одну из них. Однако оба должны использовать один и тот же язык. Первая программа примет строку в качестве ввода через STDIN, аргументы программы или параметры функции и закодирует ее, используя этот метод. Вторая программа примет строку в качестве ввода через STDIN, аргументы программы или параметры функции и расшифрует ее, используя этот метод.
Требования
Первая программа / функция
- Ввод одной строки с использованием любого метода, перечисленного выше.
- Необходимо кодировать строку с использованием диагонального стиля преобразования Берроуза-Уилера.
Вторая программа / функция
- Ввод одной строки с использованием любого метода, перечисленного выше.
- Необходимо декодировать строку с использованием диагонального стиля преобразования Берроуза-Уилера.
Ограничения
- Вы не можете использовать любые встроенные или внешние функции, которые выполняют эту задачу.
- Стандартные лазейки не допускаются.
- Обе программы / функции должны быть на одном языке.
счет
Это код гольф, поэтому самая короткая программа в байтах выигрывает .
Если мне нужно добавить больше информации, оставьте комментарий!
источник
Ответы:
CJam, (4 + 8 =) 12 байт
Программа кодирования:
Попробуйте онлайн здесь
Программа декодирования:
Попробуйте онлайн здесь
Как (точнее, почему) они работают :
Диагональное преобразование Барроуза-Уилера - это, в основном, любой другой символ строки с переносом с конца. Если мы будем рассматривать строку как двумерную матрицу из 2 столбцов, она просто сводится к преобразованию матрицы. Пример:
Представляется в виде 2D матрицы в виде
Теперь, просто прочитав это в столбце, дайте:
Что является преобразованием Барроуза-Уилера.
Декодирование просто противоположно процессу, запишите строку в виде двухстрочной двухмерной матрицы и прочитайте столбец.
Расширение кода :
Кодер:
декодер:
источник
Python 2, 61 байт
E
шифрует иD
дешифрует. Я не считаюE=
иD=
за счет.При дешифровании происходит
n
обтекание каждого символа, причемn
половина длины строки округляется вверх. Причина, по которой это инвертирует, состоит в том, что2
иn
являются инверсиями по модулю длины строки, поэтому, принимая каждыйn
й символ, инвертирует, принимая каждый2
.Если бы разрешалось использовать одну функцию, я мог бы сделать 44 байта
Шифрует, когда
b
есть,False
и дешифрует, когдаb
естьTrue
. Выражение1+len(x)**b>>b
равно[2,len(x)/2+1][b]
.источник
J 10 + 10 = 20
(Окружающие скобки не учитываются при подсчете, поскольку они не являются частью определения функции.)
Спасибо за FUZxxl за 3-байтовое улучшение.
Теперь хорошо показано, что две функции являются обратными, так как первая принимает символы с позиций, определенных списком,
#|2*i.@#
а вторая функция упорядочивает символы назад, используя тот же список, что и при упорядочивании.Попробуйте это онлайн здесь.
источник
{~#|2*i.@#
.Pyth - 5 + 11 = 16 байт
Я заметил образец! ~ Делает счастливый танец ~ Трансформация просто на самом деле просто петля через строку, выбирая все остальные элементы. Он работает только на нечетных, так как иначе он никогда не получит половину элементов. Это эквивалентно вращению матрицы шириной 2.
Кодер:
Шаг нарезки Python не зацикливается, поэтому я повторил строку.
декодер:
Снова нет обертывания для пошаговой нарезки.
источник
GNU sed -r, (20 + 104 + 1) = 125
Дополнительный +1 в счете за опцию -r для sed. Входные строки нечетной длины предполагаются.
Кодер:
декодер:
Декодер использует его
:
как временный маркерный символ, поэтому, если он появится во входной строке, вы получите неопределенное поведение. Если входная строка ограничена 95 символами ASCII, то эти маркеры могут быть заменены чем-то вне диапазона ASCII (например, BEL 0x7), чтобы это исправить.:
маркеры в начале и конце строки ввода:
вперед и второго:
назад по одному символу за раз, пока:
маркеры не окажутся по обе стороны от среднего символа:
и добавь другое:
в конец, оставив «A: B:», где A - это строка, состоящая из нечетных символов из открытого текста, а B - строка, состоящая из четных символов.:
чтобы собрать исходный текст:
маркерыисточник
JavaScript ES6, 41 + 49 = 90 байт
кодировщик
дешифратор
Это анонимные функции, поэтому я считаю только код в скобках, потому что это целое определение функции. Попробуйте это с помощью фрагмента ниже: (модифицировано для использования ES5)
Показать фрагмент кода
источник
[t=>t.replace(/./g,(_,o)=>t[o*2%t.length]),t=>t.replace(/./g,(_,o)=>t[(1+(l=t.length))/2*o%l])]
? Вы используете это как[...][0]('encode string')
и[...][1]('decode string')
. Ничто не говорит о том, что этого нельзя сделать! И вы экономите 1 байт.