Yakut
Rev 3, 55 bayt
i=1
'S, OJ1*$HCH(#%0'.bytes{|e|puts "%x"%i+=e*130&9011}
Randomra'nın fikri hakkında daha fazla bir gelişme olarak, aşağıdaki çıktı ve fark tablosunu göz önünde bulundurun. Fark tablosu daha önce olduğu gibi sıkıştırılabilir ve 65 = ikili 1000001 ile çarpılarak ve 11001100110011 maskesi uygulanarak genişletilebilir. Ancak, Ruby 8 bit karakterlerle tahmin edilebilir şekilde çalışmaz (bunları Unicode olarak yorumlama eğilimindedir).
Şaşırtıcı bir şekilde, son sütun tamamen eşittir. Bu nedenle, sıkıştırmada veriler üzerinde bir hak kayması gerçekleştirebiliriz. Bu, tüm kodların 7 bit ASCII olmasını sağlar. Genişlemede 65 yerine 65 * 2 = 130 ile çarpıyoruz.
İlk sütun tamamen eşittir. Bu nedenle, kontrol karakterlerinden kaçınmak için gerektiğinde her bir öğeye 1 (her bayta 32) ekleyebiliriz. İstenmeyen 1, 11001100110011 yerine 10001100110011 = 9011 maskesi kullanılarak çıkarılır.
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
Tablo için 15 bayt kullanmama rağmen, her baytın yalnızca 6 bitini kullanıyorum, bu da toplam 90 bit. Aslında her bayt için sadece 36 olası değer vardır, bu toplamda 2.21E23 olasılıktır. Bu, 77 bit entropi için uygundur.
Rev 2, 58 bayt, Randomra'nın artımlı yaklaşımını kullanarak
i=0
'UPEIP@bPHPBETTEPRADT'.bytes{|e|puts "%x"%i+=e*65&819}
Son olarak, saf çözeltiden daha kısa bir şey. Revra'nın bytepackleme yöntemi ile Randomra'nın artımlı yaklaşımı.
Rev 1, 72 bayt, rev 0'ın golf versiyonu
Golf nedenleriyle kodun yeniden düzenlenmesini sağlamak için taban çizgisinde bazı değişiklikler yapıldı, ancak yine de naif çözümden daha uzun sürdü.
i=0
'UPUIYD&!)$&V*).);c+*'.bytes{|e|i+=1;puts "%x"%(i/2*273+(e*65&819))}
Ofsetler, tabandaki 4 sihirli dizginin her karakterine formatta kodlanır BAC
, yani 1'ler sağ simgeyi temsil eder, 16'lar orta simgeyi temsil eder ve sol sembol 4'lerin pozisyonuna sokulur. Onları çıkarmak için, ascii kodu vermek için 65 (ikili 1000001) ile çarpılır BACBAC
, daha sonra vermek için 819 (ikili 1100110011) ile anded edilir .A.B.C
.
Bazı ascii kodları 7. bit setine sahiptir, yani kontrol karakterlerinden kaçınmak için gerekli değerden 64 daha yüksektir. Bu bit, maske 819 tarafından kaldırıldığı için, değerinin C
3 olması dışında bir aktarmaya neden olan durum hariç, bu önemsizdir . Bu sadece bir yerde düzeltilmelidir (kullanmak g
zorundayız yerine c
).
Rev 0, desteksiz versiyon
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}
Çıktı
111
121
222
423
433
433
455
465
665
675
677
778
888
998
a99
aa9
abb
abc
bbc
ccc
açıklama
Aşağıdaki çözümden, veri olarak sakladığım ofseti vererek taban çizgisini çıkarıyorum. Taban çizgisi, kodda onaltılı bir sayı olarak i/2*273
(273 ondalık = 111 hex) olarak yeniden oluşturulur.
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