Przejdź na przód ASCII do wydrukowania

19

tło

Ruch do przodu transformacji (MTF) jest kodowanie danych algorytm przeznaczony do poprawy wydajności metod kodowania entropijnego.

W algorytmie kompresji bzip2 jest on stosowany po transformacji Burrows – Wheeler (jak widać w Burrows, Wheeler i Back ), w celu przekształcenia grup powtarzających się postaci w małe, łatwo kompresowalne nieujemne liczby całkowite.

Definicja

Na potrzeby tego wyzwania zdefiniujemy wersję MTF do wydruku ASCII w następujący sposób:

Biorąc pod uwagę ciąg wejściowy s , wziąć pustą tablicę R , string d wszystkich znaków ASCII (0x20 do 0x7E) i powtarzać następujące informacje dla każdego znaku c z s :

  1. Dołącz indeks c in d do r .

  2. Przenieś c na przód d , tj. Usuń c z d i wstaw do końca.

Na koniec bierzemy elementy r jako indeksy w oryginalnym d i pobieramy odpowiednie znaki.

Przykład krok po kroku

INPUT: "CODEGOLF"

0. s = "CODEGOLF"
   d = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = []
1. s = "ODEGOLF"
   d = "C !\"#$%&'()*+,-./0123456789:;<=>?@ABDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35]
2. s = "DEGOLF"
   d = "OC !\"#$%&'()*+,-./0123456789:;<=>?@ABDEFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47]
3. s = "EGOLF"
   d = "DOC !\"#$%&'()*+,-./0123456789:;<=>?@ABEFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37]
4. s = "GOLF"
   d = "EDOC !\"#$%&'()*+,-./0123456789:;<=>?@ABFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38]
5. s = "OLF"
   d = "GEDOC !\"#$%&'()*+,-./0123456789:;<=>?@ABFHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40]
6. s = "LF"
   d = "OGEDC !\"#$%&'()*+,-./0123456789:;<=>?@ABFHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3]
7. s = "F"
   d = "LOGEDC !\"#$%&'()*+,-./0123456789:;<=>?@ABFHIJKMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3 45]
8. s = ""
   d = "FLOGEDC !\"#$%&'()*+,-./0123456789:;<=>?@ABHIJKMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3 45 41]

OUTPUT: "COEFH#MI"

Zadanie

Napisz program lub funkcję, która implementuje drukowalną MTF ASCII (jak zdefiniowano powyżej).

Przypadki testowe

Input:  Programming Puzzles & Code Golf
Output: Prpi"do lp%((uz rnu&3!P/o&$U$(p

Input:  NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN BATMAN!
Output: Na! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!"DDUP"%'

Input:  Two more questions and I have bzip2 in less than 100 bytes!
Output: Twp#o"si$sv#uvq(u$(l#o#W!r%w+$pz,xF%#,"x(. #0--'$GG ".z(**:

Dodatkowe zasady

  • Nie można użyć żadnego wbudowanego operatora, który oblicza MTF ciągu.

  • Twój kod może wydrukować końcowy znak nowej linii, jeśli wybierzesz STDOUT jako wynik.

  • Twój kod musi działać na każdym wprowadzeniu 1000 lub mniej znaków drukowalnych ASCII (0x20 do 0x7E).

  • Obowiązują standardowe zasady gry w golfa. Najkrótsze przesłanie w bajtach wygrywa.

Dennis
źródło
1
„Nanananana DDUP!” po prostu nie jest tak chwytliwy jak „Batman!” ...
Klamka
8
@Doorknob: Ale Batman nie jest łatwo ściśliwy.
Dennis
Czy możemy wydrukować wynik w postaci funkcji powrotu zamiast drukowania go do STDOUT?
Fatalize
@Fatalize: To najbardziej naturalna forma danych wyjściowych funkcji, więc tak. Nawiasem mówiąc, mamy domyślne ustawienia I / O , więc jeśli pytanie wyraźnie nie mówi inaczej, to zawsze jest dozwolone.
Dennis

Odpowiedzi:

6

CJam, 20

'¡,q{_C#c' ,C+@|}fC;

Wypróbuj online

Wyjaśnienie:

'¡,      make a string of characters with codes from 0 to 160 (a modified "d")
         could have been to 126 but stackexchange doesn't like the DEL character
q        read the input (s)
{…}fC    for each character C in s
  _      duplicate the d string
  C#     find the index of C in d
  c      convert to character (this is the result)
  ' ,    make a string of characters from 0 to 31
  C+     append C to the string
  @      bring d to the top
  |      set union, preserving order; effectively, C is moved to position 32
         this is the updated d string
;        pop the last d
aditsu
źródło
6

Struś , 46 45 znaków

Nie mam numeru wersji w nagłówku, ponieważ tak naprawdę jest to tylko ostatni zatwierdzenie . Dodałem Ooperatora (kod ascii do łańcucha) po wydaniu najnowszej wersji (ale jeszcze przed opublikowaniem tego wyzwania).

{a95,{32+O}%:d3@{:x\.3@?3@\+\x-x\+}/;{d=}%s*}

Wyjaśnienie:

a             this is the "r" array (a is short for [], empty array)
95,{32+O}%:d  this is the "d" array
3@{...}/      for each character in the input (as an "argument")...
  :x            store in variable x (stack is now [r d c])
  \.3@?         find index in d     (stack is now [r d idx])
  3@\+          append index to r   (stack is now [d modified_r])
  \x-           remove char from d, and then...
  x\+           prepend char to d   (stack is now [modified_r modified_d])
;             throw away modified_d
{d=}%         map r to indices of (original) d
s*            join (s is short for ``, empty string)
Klamka
źródło
Zastanawiam się, czy PPCG przechodzi z „kodowania tego zadania w najbardziej zwięzły możliwy sposób w ulubionym języku” na „zaprojektowanie własnego języka programowania w celu rozwiązania typowego zadania golfowego krótszego niż golfscript”
John Dvorak
1
@AlexA. ... czekaj, tak to napisane? całe moje życie było kłamstwem
Klamka
@JanDvorak Ostrich jest prawie identyczny jak GolfScript. Jedynym prawdziwym powodem, dla którego go stworzyłem, jest to, że: a) GolfScript irytująco nie ma REPL i b.) Brakuje kilku operatorów / funkcji (zmiennoprzecinkowe, I / O itp.). A projektowanie języka i tak jest fajne!
Klamka
3

Python 3, 88

*d,=range(127)
for c in input():y=d.index(ord(c));d[:32]+=d.pop(y),;print(chr(y),end='')

Wykorzystuję kilka pomysłów z mojego rozwiązania CJam.
-4 bajty należą do Sp3000 :)

aditsu
źródło
2

SWI-Prolog, 239 197 189 bajtów

a(S):-l([126],X),a(S,X,[],R),b(R,X).
a([A|T],X,S,R):-nth0(I,X,A,Z),(a(T,[A|Z],[I|S],R);R=[I|S]).
b([A|T],X):-(b(T,X);!),nth0(A,X,E),put(E).
l([B|R],Z):-A is B-1,X=[A,B|R],(A=32,Z=X;l(X,Z)).

Przykład: a(`Two more questions and I have bzip2 in less than 100 bytes!`).wyniki:

Twp#o"si$sv#uvq(u$(l#o#W!r%w+$pz,xF%#,"x(. #0--'$GG ".z(**:

(a true .potem oczywiście)

Uwaga: twoja wersja SWI-Prolog musi być jedną z nowszych, w których backquote `reprezentuje ciągi kodów. Ciągi kodu były reprezentowane przez podwójne cudzysłowy "w starszych wersjach.

Fatalizować
źródło
2

Python 2, 137 110 104

Nie było trudne do wdrożenia, ale może nadal można grać w golfa?

Wypróbuj tutaj

e=d=map(chr,range(32,127))
r=""
for c in raw_input():n=e.index(c);r+=d[n];e=[e[n]]+e[:n]+e[n+1:]
print r
mbomb007
źródło
1
Myślę, że lepiej jest zrobić mapę listy e=d=map(chr,range(32,127))w Pythonie 2, choć musisz ją ulepszyć, eaby obsługiwała listę.
xnor
@xnor Thanks. Próbowałem także użyć e=[e.pop(n)]+e, ale to nie działa. Dlaczego?
mbomb007,
Masz e=d=, więc kiedy wyskakujesz z e, wyskakujesz również d. Spróbować d=e[:].
Sp3000,
1
Ale w tym momencie prawdopodobnie lepiej po prostu zrobić n=e.index(ord(c));r+=chr(n+32);i upuścićd
Sp3000,
1

Pyth, 24 bajty

JK>95CM127s@LKxL~J+d-Jdz

Demonstracja. Uprząż testowa.

Pierwszy kawałek. JK>95CM127tworzy niezbędną listę i zapisuje ją w Joraz K. ~J+d-Jdwykonuje aktualizację listy, a jednocześnie xL ... zodwzorowuje znaki wejściowe na ich pozycje na liście. Na koniec s@LKkonwertuje te indeksy na znaki z oryginalnej listy.

isaacg
źródło
1

Haskell, 120 bajtów

e#s=[b|(b,a)<-zip[0..]s,a==e]!!0
a=[' '..'~']
f=snd.foldl(\(d,r)e->(e:take(e#d)d++tail(drop(e#d)d),r++[a!!(e#d)]))(a,[])

Przykład użycia: f "CODEGOLF"->"COEFH#MI"

Jak to działa: #jest funkcją indeksu, która zwraca pozycję ein s(nie może używać natywnego Haskell z elemIndexpowodu drogiego import). Główna funkcja fpodąża za wzorem zagięcia, w którym aktualizuje ciąg pozycji di ciąg wyniku rpodczas przechodzenia przez ciąg wejściowy.

nimi
źródło