2013-08-08 18 views
7

Widziałem więc ten inteligentny temat na temat "Programowania puzzli i kodowania golfa": We're not strangers.... Najlepszą odpowiedzią na to jest kod PHP drukujący słowa: Never Gonna Give You Up. Ma tylko 543 bajty długości.Kod inteligentnej kompresji PHP

Próbowałem zrozumieć ten kod PHP, ale nie mogę zrozumieć, jak to działa. Myślę, że to kompresja oparta gramatyki, ale nie mam pojęcia, jak można użyć niezgłoszonych stałe jak w

<?php range('-', T); 

Więc tutaj jest kod. Jak to działa?

<?=str_replace(range('-',T),split(q," 
I justCannaLE?2Gotta >u=Msta=.q 
Ng1Nlet? downNrun<rH=5desMt?N>cryNsayRoodbyeNtE< lie5hurt?q 

We'T3n [email protected] s8lSg6r hear9<ch: but6;Lo7hyL7BInsideCe both3Cha9Ro: S 
We3KeRa45we;QplBq1)O)NgiT, nPgiT 
(GqiT? upq howFJeel: 
q knowqmeq<= q 
YHq8sqo qt's beenqingq'req aqndqmake? q yHq othMqAqay it 
q wqDqellq I'mqGqouqIq fqLhq tqerq 
NPq 
(OohqeTrQqRSna q gqonqve"),"We; n7trangMsL8loT63Ke rules5s8d8I 
AJull commit4nt'sChatFKink: of6CHldn'tRetKisJrom<[email protected]/A= if?<sk 42DS'tLE 4?;Lo8bli=L7ee.. 
O,R1)O,R001)/-.."); 

Zobacz .

Odpowiedz

7

Przeanalizujmy parametrów str_replace jeden po drugim.

range('-',T) 

Funkcja range() zwraca tablicę, która ma elementy rozciąga się od pierwszego parametru do drugiego parametru. Postacie są uznawane przez ich wartości ASCII, więc wynik jest

Array 
(
    [0] => - 
    [1] => . 
    [2] =>/
    [3] => 0 
    [4] => 1 
    [5] => 2 
    [6] => 3 
    [7] => 4 
    [8] => 5 
    [9] => 6 
    [10] => 7 
    [11] => 8 
    [12] => 9 
    [13] => : 
    [14] => ; 
    [15] => < 
    [16] => = 
    [17] => > 
    [18] => ? 
    [19] => @ 
    [20] => A 
    [21] => B 
    [22] => C 
    [23] => D 
    [24] => E 
    [25] => F 
    [26] => G 
    [27] => H 
    [28] => I 
    [29] => J 
    [30] => K 
    [31] => L 
    [32] => M 
    [33] => N 
    [34] => O 
    [35] => P 
    [36] => Q 
    [37] => R 
    [38] => S 
    [39] => T 
) 

Dlaczego T zamiast "T"? PHP ma pomyłkę, która sprawia, że ​​niezdefiniowane stałe są traktowane jako ciągi o takiej samej treści jak nazwa stałej. Stała T nie jest zdefiniowana, więc jest taka sama jak "T", która zapisuje dwa znaki dla celów golfa kodu. To samo dotyczy późniejszej wersji. Jeśli serwer zgłosił błąd, wyświetli ostrzeżenie o niezdefiniowanej stałej.

split(q,"I justCannaLE?2Gotta >u=Msta=.q..."); 

ten dzieli ciąg do tablicy Pod q znaków. Znowu tworzy to krótszy kod niż użycie literału tablicowego. Wynik:

Array 
(
    [0] => 
I justCannaLE?2Gotta >u=Msta=. 
    [1] => 
Ng1Nlet? downNrun<rH=5desMt?N>cryNsayRoodbyeNtE< lie5hurt? 
    [2] => 

We'T3n [email protected] s8lSg6r hear9<ch: but6;Lo7hyL7BInsideCe both3Cha9Ro: S 
We3KeRa45we;QplB 
    [3] => 1)O)NgiT, nPgiT 
(G 
    [4] => iT? up 
    [5] => howFJeel: 

    [6] => know 
    [7] => me 
    [8] => <= 
    [9] => 
YH 
    [10] => 8s 
    [11] => o 
    [12] => t's been 
    [13] => ing 
    [14] => 're 
    [15] => a 
    [16] => nd 
    [17] => make? 
    [18] => yH 
    [19] => othM 
    [20] => A 
    [21] => ay it 

    [22] => w 
    [23] => D 
    [24] => ell 
    [25] => I'm 
    [26] => G 
    [27] => ou 
    [28] => I 
    [29] => f 
    [30] => Lh 
    [31] => t 
    [32] => er 
    [33] => 
NP 
    [34] => 
(Ooh 
    [35] => eTrQ 
    [36] => RSna 
    [37] => g 
    [38] => on 
    [39] => ve 
) 

Ostatnim parametrem jest ciąg docelowy.

"We; n7trangMsL8loT63Ke rules5s8d8I 
AJull commit4nt'sChatFKink: of6CHldn'tRetKisJrom<[email protected]/A= if?<sk 42DS'tLE 4?;Lo8bli=L7ee.. 
O,R1)O,R001)/-.." 

Jeśli zdasz tablic do str_replace() jak igły i stogu siana, wymiana odbywa się po jednym na raz. Dla uproszczenia, bierzmy tylko "We; n7trangMs" jako ciąg tagów i zacznijmy zastępować od ;.Pierwszy krok po wymianie "7" z "8s" (odpowiednia wymiana drugiej tablicy)

"We; n8strangMs" 

Następnie wymienić "8" z "o "

"We; no strangMs" 

";" z "'re"

"We're no strangMs" 

"M" z "er"

W skrócie, jest to podstawowy algorytm kompresji, w którym można znaleźć sekwencje znaków, które powtarzają się w oryginalnym tekście i zastępują je pojedynczym znakiem. Podczas dekompresji ten znak jest zastępowany oryginalną sekwencją. Wykonując iteracyjne postępy, możesz ponownie skompresować tekst skompresowany raz ("o s" =>"8s" =>"7").

+1

Dziękuję za tę bardzo dobrą odpowiedź. Brakowało mi tutaj tego, że wielokrotnie zamieniasz. Jaki byłby najprostszy sposób kompresji tekstu? (W jaki sposób autor znalazł skompresowany ciąg?) – Imateapot

+0

Autor prawdopodobnie użył jakiegoś algorytmu kompresji. Robienie tego ręcznie wymagałoby wiele pracy. – JJJ

+0

Czy mogę znaleźć kod kompresji, odwracając kod dekompresji? – Imateapot

1

Wypróbuj!

Nieokreślone stałe są traktowane jako ciągi. To, co wygląda na to, ze zawiadomień włączona:

Notice: Use of undefined constant T - assumed 'T' in D:\www\htdocs\test\index.php on line 1 
Notice: Use of undefined constant q - assumed 'q' in D:\www\htdocs\test\index.php on line 1 
Deprecated: Function split() is deprecated in D:\www\htdocs\test\index.php on line 12 
We're no strangers to love 
You know the rules and so do I 
[...] 
Never gonna say goodbye 
Never gonna tell a lie and hurt you 
+0

Wypróbowałem to i nie zwróciło to uwagi z 'T' i' q'. Ale jeśli zastąpię te dwie stałe innymi literami, pojawią się uwagi. Jaki byłby cel użycia niezdefiniowanych stałych? – Imateapot

+0

O, widzę, są one interpretowane jako łańcuchy znaków i podnoszą informację (były ukryte w łączu ideowym). Ale co z częścią kompresji? – Imateapot

+0

@Imateapot: cel jest ustalony przez zasady gry w golfa: używaj jak najmniej znaków - 'T' jest o dwa znaki krótszy niż' 'T'' – cypherabe