Rubino
Rev 3, 55bytes
i=1
'S, OJ1*$HCH(#%0'.bytes{|e|puts "%x"%i+=e*130&9011}
Come ulteriore sviluppo dell'idea di Randomra, prendere in considerazione l'output e la tabella delle differenze di seguito. La tabella delle differenze può essere compressa come prima ed espansa moltiplicando per 65 = binario 1000001 e applicando una maschera 11001100110011. Tuttavia, Ruby non funziona in modo prevedibile con caratteri a 8 bit (tende a interpretarli come Unicode).
Sorprendentemente, l'ultima colonna è del tutto uniforme. Per questo motivo, nella compressione possiamo eseguire uno spostamento dei diritti sui dati. Ciò garantisce che tutti i codici siano ASCII a 7 bit. In espansione, moltiplichiamo semplicemente per 65 * 2 = 130 anziché 65.
Anche la prima colonna è del tutto uniforme. Pertanto, è possibile aggiungere 1 a ciascun elemento (32 per ogni byte) ove necessario, per evitare qualsiasi carattere di controllo. 1 indesiderato viene rimosso utilizzando la maschera 10001100110011 = 9011 anziché 11001100110011.
Solution 59 of document linked in question
Start0001
Out Diff
2223 2222
2433 0210
2433 0000
4445 2012
6555 2110
6577 0022
6687 0110
6887 0200
8897 2010
aa99 2202
caa9 2010
cab9 0010
cbbb 0102
cdbd 0202
cddd 0020
Sebbene io usi 15 byte per la tabella, uso davvero solo 6 bit di ogni byte, per un totale di 90 bit. Vi sono infatti solo 36 possibili valori per ogni byte, che è 2.21E23 possibilità in totale. Ciò si adatterebbe a 77 bit di entropia.
Rev 2, 58 byte, usando l'approccio incrementale di Randomra
i=0
'UPEIP@bPHPBETTEPRADT'.bytes{|e|puts "%x"%i+=e*65&819}
Finalmente qualcosa di più corto della soluzione ingenua. Approccio incrementale di Randomra, con il metodo bytepacking di Rev 1.
Rev 1, 72 byte, versione golfata di rev 0
Sono state apportate alcune modifiche alla linea di base per adattarsi al riordino del codice per motivi di golf, ma sono ancora arrivati più a lungo della soluzione ingenua.
i=0
'UPUIYD&!)$&V*).);c+*'.bytes{|e|i+=1;puts "%x"%(i/2*273+(e*65&819))}
Gli offset sono codificati in ciascun carattere della stringa magica nel formato base 4 BAC
, ovvero con gli 1 che rappresentano il simbolo di destra, i 16 che rappresentano il simbolo di mezzo e il simbolo di sinistra calzato nella posizione del 4. Per estrarli, il codice ascii viene moltiplicato per 65 (binario 1000001) per dare BACBAC
, quindi viene aggiunto con 819 (binario 1100110011) per dare .A.B.C
.
Alcuni dei codici ascii hanno il settimo bit impostato, cioè sono 64 più alti del valore richiesto, per evitare i caratteri di controllo. Poiché questo bit viene rimosso dalla maschera 819, ciò è irrilevante, tranne quando il valore di C
è 3, che provoca un riporto. Questo deve essere corretto in un solo posto (invece di g
usarlo c
.)
Rev 0, versione non golfata
a= %w{000 010 000 201 100 100 011 021 110 120 011 112 111 221 211 221 122 123 112 222}
i=2
a.each{|e|puts "%x"%(i/2*273+e.to_i(16));i+=1}
Produzione
111
121
222
423
433
433
455
465
665
675
677
778
888
998
a99
aa9
abb
abc
bbc
ccc
Spiegazione
Dalla seguente soluzione, sottraggo la linea di base, fornendo l'offset che memorizzo come dati. La linea di base viene rigenerata come numero esadecimale nel codice di i/2*273
(273 decimale = 111 esadecimale).
solution baseline offset
AAA AAA 000
ABA AAA 010
BBB BBB 000
DBC BBB 201
DCC CCC 100
DCC CCC 100
DEE DDD 011
DFE DDD 021
FFE EEE 110
FGE EEE 120
FGG FFF 011
GGH FFF 112
HHH GGG 111
IIH GGG 221
JII HHH 211
JJI HHH 221
JKK III 122
JKL III 123
KKL JJJ 112
LLL JJJ 222