Рубін
Вихід 3, 55 байт
i=1
'S, OJ1*$HCH(#%0'.bytes{|e|puts "%x"%i+=e*130&9011}
Як подальший розвиток ідеї Randomra розглянемо таблицю результатів та різниці нижче. Таблицю різниць можна стиснути, як і раніше, і розширити, помноживши на 65 = двійковий 1000001 і застосувавши маску 11001100110011. Однак, Ruby не працює передбачувано з 8-бітовими символами (вона, як правило, інтерпретує їх як Unicode.)
Дивно, але останній стовпець цілком рівний. Через це при стисненні ми можемо здійснити зміну прав на дані. Це гарантує, що всі коди є 7-бітними ASCII. При розширенні ми просто множимо на 65 * 2 = 130 замість 65.
Перший стовпець також цілком рівний. Тому ми можемо додати 1 до кожного елемента (32 у кожному байті), де це необхідно, щоб уникнути будь-яких контрольних символів. Небажаний 1 видаляється за допомогою маски 10001100110011 = 9011 замість 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
Хоча я використовую 15 байт для таблиці, я реально використовую лише 6 біт кожного байта, що в цілому становить 90 біт. Насправді існує лише 36 можливих значень для кожного байта, що в цілому становить 2.21E23. Це може відповідати 77 бітам ентропії.
Rev 2, 58 байт, використовуючи поступовий підхід Randomra
i=0
'UPEIP@bPHPBETTEPRADT'.bytes{|e|puts "%x"%i+=e*65&819}
Нарешті, щось коротше, ніж наївне рішення. Інкрементальний підхід Randomra за допомогою методу bytepacking Rev 1.
Ред 1, 72 байти, гольф-версія версії 0
Деякі зміни в базовій лінії були внесені, щоб забезпечити переупорядкування коду з міркувань гольфу, але все-таки прийшли довше, ніж наївне рішення.
i=0
'UPUIYD&!)$&V*).);c+*'.bytes{|e|i+=1;puts "%x"%(i/2*273+(e*65&819))}
Зсуви кодуються у кожному символі магічної струни в базі 4 у форматі BAC
, тобто 1-ма символом праворуч, 16-ти символом середнього, а символ лівої руки переходить у положення 4. Для того, щоб витягнути їх, код ascii множиться на 65 (двійковий 1000001), щоб дати BACBAC
, тоді він anded з 819 (двійковий 1100110011), щоб дати .A.B.C
.
Деякі коди ascii мають 7-й бітовий набір, тобто вони на 64 перевищують необхідне значення, щоб уникнути контрольних символів. Оскільки цей біт видаляється за допомогою маски 819, це не має наслідків, за винятком випадків, коли значення C
дорівнює 3, що спричиняє перенесення. Це потрібно виправити лише в одному місці (замість того g
, щоб використовувати c
.)
Rev 0, неліточна версія
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}
Вихідні дані
111
121
222
423
433
433
455
465
665
675
677
778
888
998
a99
aa9
abb
abc
bbc
ccc
Пояснення
З наступного рішення я віднімаю базову лінію, надаючи зміщення, яке я зберігаю як дані. Базова лінія регенерується у шістнадцятковому номері в коді на i/2*273
(273 десятків = 111 шістнадцять.)
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