2013-08-08 20 views
7

Così ho visto questo argomento intelligente su "Programmazione di puzzle e codice golf": We're not strangers.... La migliore risposta è il codice PHP che stampa il testo di Never Gonna Give You Up. È lungo solo 543 byte.Codice di compressione Smart PHP

Ho cercato di capire questo codice PHP, ma non riesco a capire come funziona. Penso che sia una compressione di grammatica base, ma non ho idea di come si possa utilizzare le costanti non dichiarati come in

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

Quindi, ecco il codice. Come funziona?

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

Vedere it working on Ideone.

risposta

7

Analizziamo i parametri str_replace uno per uno.

range('-',T) 

La funzione range() restituisce un array con gli elementi che vanno dalla prima parametro per il secondo parametro. I personaggi sono considerati dai loro valori ASCII, quindi il risultato è

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 
) 

Perché T invece di "T"? PHP ha una disfunzione che fa valutare costanti indefinite come stringhe con lo stesso contenuto del nome della costante. La costante T non è definita quindi è la stessa di "T" che salva due caratteri per scopi di codice golf. Lo stesso vale per q in seguito. Se il server ha segnalazioni di errori, mostrerà un avviso su una costante indefinita.

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

Questo divide la stringa in un array ai q caratteri. Di nuovo, questo rende il codice più corto rispetto all'utilizzo di un letterale di array. Il risultato:

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 
) 

Il parametro finale è la stringa di destinazione.

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

Se si passa le matrici a str_replace() come ago e pagliaio, la sostituzione è fatto uno alla volta. Per semplicità, prendiamo solo "We; n7trangMs" come stringa di taget e iniziamo a sostituire da ;.Il primo passo dopo la sostituzione "7" con "8s" (corrispondente sostituzione del secondo array):

"We; n8strangMs" 

quindi sostituire "8" con "o "

"We; no strangMs" 

";" con "'re"

"We're no strangMs" 

"M" con "er"

"We're no strangers" 

In breve, si tratta di un algoritmo di compressione di base dove si trovano le sequenze di caratteri che si ripetono all'interno del testo originale e sostituirli con un singolo carattere. Quando si decomprime quel personaggio viene sostituito con la sequenza originale. Eseguendo il progresso in modo iterativo è possibile comprimere nuovamente il testo compresso una volta ("o s" =>"8s" =>"7").

+1

Grazie per questa ottima risposta. Quello che mi mancava qui è che tu sostituisci più volte. Quale sarebbe il modo più semplice per comprimere il testo? (Come ha trovato l'autore la stringa compressa?) – Imateapot

+0

Probabilmente l'autore ha utilizzato un algoritmo di compressione. Farlo manualmente sarebbe molto lavoro. – JJJ

+0

Posso trovare il codice di compressione "invertendo" il codice di compressione? – Imateapot

1

Provalo!

Si presume che le costanti non definite siano stringhe. Questo è ciò che sembra con le comunicazioni abilitati:

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

Ho provato, e non ha sollevato alcun avviso con 'T' e' q'. Ma se sostituisco queste due costanti con altre lettere, vengono visualizzate delle notifiche. Quale sarebbe lo scopo dell'uso di costanti non definite? – Imateapot

+0

Oh, capisco, questi sono interpretati come archi e Fanno alzare un avviso (erano nascosti sul collegamento ideone). Ma per quanto riguarda la parte di compressione? – Imateapot

+0

@Imateapot: lo scopo è fissato dalle regole del codice golf: usa il minor numero di caratteri possibile - 'T' è due caratteri più corto di' 'T'' – cypherabe