Wprowadzenie
W tym wyzwaniu rozwiążesz przekątne transformacje Burrows-Wheeler. Oto ogólny przegląd tego, czym jest przekątna transformata Burrowsa-Wheelera. Aby zakodować wiadomość, musisz najpierw zagwarantować, że ma ona nieparzystą długość (tj. 5, 7, 9 itd.). Następnie należy wykonać siatkę, n
przez n
, gdzie n
jest długością wiadomości. Pierwszy wiersz to oryginalna wiadomość. Każdy rząd po nim jest rzędem nad nim, ale przesunął 1 znak w lewo, a pierwszy znak przesuwa się do tyłu. Na przykład:
Hello World
ello WorldH
llo WorldHe
lo WorldHel
o WorldHell
WorldHello
WorldHello
orldHello W
rldHello Wo
ldHello Wor
dHello Worl
Następnie weź każdą literę na przekątnej NW do SE i umieść ją w nowym ciągu:
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
Twoja zakodowana wiadomość to HloWrdel ol
. Aby zdekodować, najpierw weź długość zakodowanej wiadomości, dodaj 1 i podziel przez 2. Zadzwoń pod ten numer x
. Teraz, gdy wiemy x
, zaczynając od pierwszej litery, każda litera jest x
za ostatnią, zapętlając się. Na przykład:
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
Teraz wystarczy zmienić kolejność liter we właściwej kolejności, aby uzyskać Hello World
!
Wyzwanie
Wyzwanie polega na napisaniu dwóch programów, funkcji lub jednego z nich. Jednak oba muszą używać tego samego języka. Pierwszy program zaakceptuje ciąg jako dane wejściowe przez STDIN, argumenty programu lub parametry funkcji i zakoduje go przy użyciu tej metody. Drugi program zaakceptuje ciąg jako dane wejściowe przez STDIN, argumenty programu lub parametry funkcji i zdekoduje go przy użyciu tej metody.
Wymagania
Pierwszy program / funkcja
- Pojedynczy ciąg wejściowy przy użyciu dowolnej metody wymienionej powyżej.
- Należy zakodować ciąg przy użyciu ukośnego stylu transformacji Burrows-Wheeler.
Drugi program / funkcja
- Pojedynczy ciąg wejściowy przy użyciu dowolnej metody wymienionej powyżej.
- Należy zdekodować ciąg przy użyciu ukośnego stylu transformacji Burrows-Wheeler.
Ograniczenia
- Nie można używać żadnych wbudowanych ani zewnętrznych funkcji, które realizują to zadanie.
- Standardowe luki są niedozwolone.
- Oba programy / funkcje muszą być w tym samym języku.
Punktacja
To jest kod golfowy, więc wygrywa najkrótszy program w bajtach .
Jeśli muszę dodać więcej informacji, zostaw komentarz!
źródło
Odpowiedzi:
CJam, (4 + 8 =) 12 bajtów
Program do kodowania:
Wypróbuj online tutaj
Program dekodujący:
Wypróbuj online tutaj
Jak (a raczej dlaczego) działają :
Transformacja Diagonal Burrows-Wheeler to w zasadzie każda inna postać struny, z zawijaniem od końca. Jeśli traktujemy Łańcuch jako matrycę 2D złożoną z 2 kolumn, sprowadza się on po prostu do przekształcenia macierzy. Przykład:
Jest reprezentowany jako macierz 2D jako
Teraz, po prostu czytając kolumnę, podaj:
Która jest transformacją Burrowsa-Wheelera.
Dekodowanie jest po prostu odwrotnością procesu, zapisz ciąg jako 2-rzędową matrycę 2D i odczytaj kolumnę.
Rozszerzenie kodu :
Enkoder:
Dekoder:
źródło
Python 2, 61 bajtów
E
szyfruje iD
odszyfrowuje. Nie liczęE=
iD=
za wynik.Odszyfrowanie zajmuje co
n
dziesiąty znak, w którymn
długość połowy łańcucha jest zaokrąglona w górę. Powodem tego jest to, że odwraca2
in
są odwrotności modulo długość łańcucha, więc biorąc con
th odwraca znaków biorąc pod każdą2
nd jeden.Jeśli używanie jednej funkcji byłoby dozwolone, mógłbym zrobić 44 bajty
Szyfruje kiedy
b
jestFalse
i odszyfrowuje kiedyb
jestTrue
. Wyrażenie1+len(x)**b>>b
jest równe[2,len(x)/2+1][b]
.źródło
J, 10 + 10 = 20
(Nawiasy klamrowe nie są wliczane do wyniku, ponieważ nie są częścią definicji funkcji.)
Dzięki za FUZxxl za 3-bajtową poprawę.
Teraz jest ładnie pokazane, że dwie funkcje są odwrócone, ponieważ pierwsza pobiera znaki z pozycji określonych przez listę,
#|2*i.@#
a druga funkcja porządkuje znaki, używając tej samej listy jako kolejności.Wypróbuj online tutaj.
źródło
{~#|2*i.@#
.Pyth - 5 + 11 = 16 bajtów
Zauważyłem wzór! ~ Czy taniec szczęśliwy ~ Transformacja po prostu zapętla strunę, zbierając wszystkie pozostałe elementy. Działa tylko na nieparzystych, ponieważ w przeciwnym razie nigdy nie uzyskałby połowy elementów. Jest to równoważne z obrotem 2 szerokiej matrycy.
Enkoder:
Krojenie kroków Pythona nie zapętla się, więc powtórzyłem ciąg.
Dekoder:
Znowu nie owijamy się w krojenie krokowe.
źródło
GNU sed -r, (20 + 104 + 1) = 125
Dodatkowy +1 w wyniku dotyczy opcji -r sed. Zakłada się łańcuchy wejściowe o nieparzystej długości.
Enkoder:
Dekoder:
Dekoder wykorzystuje
:
jako tymczasowy znak znacznika, więc jeśli pojawi się w ciągu wejściowym, otrzymasz niezdefiniowane zachowanie. Jeśli ciąg wejściowy jest ograniczony do 95 znaków ASCII, wówczas znaczniki te można zastąpić czymś spoza zakresu ASCII (np. BEL 0x7), aby to naprawić.:
znaczniki na początku i na końcu ciągu wejściowego:
przodu i drugą:
do tyłu, aż:
znaczniki znajdą się po obu stronach środkowej postaci:
i dodaj kolejny:
na końcu, pozostawiając „A: B:”, gdzie A to ciąg złożony z nieparzystych znaków z tekstu jawnego, a B to ciąg złożony z parzystych znaków:
aby ponownie złożyć tekst jawny:
markeryźródło
JavaScript ES6, 41 + 49 = 90 bajtów
Enkoder
Dekoder
Są to funkcje anonimowe, więc liczę kod tylko w nawiasach, ponieważ jest to cała definicja funkcji. Wypróbuj go z poniższym fragmentem: (zmodyfikowano, aby używać ES5)
Pokaż fragment kodu
źródło
[t=>t.replace(/./g,(_,o)=>t[o*2%t.length]),t=>t.replace(/./g,(_,o)=>t[(1+(l=t.length))/2*o%l])]
:? Używasz go jak[...][0]('encode string')
i[...][1]('decode string')
. Nic nie mówi, że nie da się tego zrobić! I oszczędzasz 1 bajt.