2013-08-08 4 views
7

So sah ich dieses intelligente Thema auf "Programmierung von Puzzles und Code Golf": We're not strangers.... Die beste Antwort ist PHP Code, der den Songtext Never Gonna Give You Up druckt. Es ist nur 543 Bytes lang.Smart PHP-Komprimierungscode

Ich habe versucht, diesen PHP-Code zu verstehen, aber ich kann nicht verstehen, wie das funktioniert. Ich denke, es ist eine Grammatik basierte Kompression, aber ich habe keine Ahnung, wie man nicht deklarierte Konstanten wie nutzen könnten in

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

So, hier ist der Code. Wie funktioniert das?

<?=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)/-.."); 

Siehe it working on Ideone.

Antwort

7

Lassen Sie uns die str_replace Parameter einzeln analysieren.

range('-',T) 

range() Die Funktion gibt ein Array, das die Elemente spannt sich von dem ersten Parameter auf den zweiten Parameter aufweist. Die Zeichen werden durch ihre ASCII-Werte betrachtet, so ist das Ergebnis

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 
) 

Warum T statt "T"? PHP hat ein falsches Merkmal, das dazu führt, dass undefinierte Konstanten als Strings mit dem gleichen Inhalt wie der Name der Konstanten ausgewertet werden. Die Konstante T ist nicht definiert und entspricht "T", die zwei Zeichen für Code-Golf-Zwecke speichert. Das gleiche gilt für q später. Wenn der Server eine Fehlermeldung meldet, wird eine Warnung über eine nicht definierte Konstante angezeigt.

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

Diese spaltet die Zeichenfolge in ein Array an den q Zeichen. Dies führt wiederum zu kürzerem Code als bei Verwendung eines Array-Literals. Das Ergebnis:

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 
) 

Der letzte Parameter ist die Zielzeichenfolge.

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

Wenn Sie Arrays str_replace() als Nadel und Heuhaufen übergeben, wird der Ersatz einer nach dem anderen gemacht. Der Einfachheit halber nehmen wir nur "We; n7trangMs" als die taget Zeichenfolge und beginnen, von ; zu ersetzen.Der erste Schritt nach "7" mit "8s" (dem entsprechenden Ersatz in der zweiten Array) ersetzt:

"We; n8strangMs" 

Dann "8" mit "o "

"We; no strangMs" 
ersetzen

";" mit "'re"

"We're no strangMs" 

"M" mit "er"

Kurz gesagt, es ist ein grundlegender Komprimierungsalgorithmus, bei dem Sie Zeichenfolgen finden, die sich im Originaltext wiederholen und durch ein einzelnes Zeichen ersetzen. Beim Dekomprimieren wird dieses Zeichen durch die Originalsequenz ersetzt. Indem Sie den Fortschritt iterativ ausführen, können Sie den einmal komprimierten Text erneut komprimieren ("o s" =>"8s" =>"7").

+1

Danke für diese sehr gute Antwort. Was ich hier vermisste ist, dass Sie mehrere Male ersetzen. Was wäre der einfachste Weg, den Text zu komprimieren? (Wie hat der Autor die komprimierte Zeichenfolge gefunden?) – Imateapot

+0

Der Autor hat wahrscheinlich einen Komprimierungsalgorithmus verwendet. Es manuell zu tun wäre eine Menge Arbeit. – JJJ

+0

Kann ich den Komprimierungscode finden, indem ich den Dekomprimierungscode invertiere? – Imateapot

1

Probieren Sie es aus!

Nicht definierte Konstanten werden als Zeichenfolgen angenommen. Dies ist, wie es mit bemerkt sieht aktiviert:

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

Ich habe es versucht, und es hat keinen Hinweis mit "T" und "q". Aber wenn ich diese beiden Konstanten durch andere Buchstaben ersetze, erscheinen Hinweise. Was wäre der Zweck der Verwendung nicht definierter Konstanten? – Imateapot

+0

Oh, ich sehe, diese werden als Strings interpretiert und sie erheben eine Notiz (sie waren auf dem Ideon Link versteckt). Aber was ist mit dem Kompressionsteil? – Imateapot

+0

@Imateapot: der Zweck wird durch die Regeln des Codes Golf festgelegt: Verwenden Sie so wenig Zeichen wie möglich- 'T' ist zwei Zeichen kürzer als' 'T'' – cypherabe