Rubi
Rev 3, 55 bytes
i=1
'S, OJ1*$HCH(#%0'.bytes{|e|puts "%x"%i+=e*130&9011}
Como um desenvolvimento adicional da idéia da Randomra, considere a tabela de saída e diferença abaixo. A tabela de diferenças pode ser compactada como antes e expandida multiplicando por 65 = binário 1000001 e aplicando uma máscara 11001100110011. No entanto, Ruby não funciona previsivelmente com caracteres de 8 bits (tende a interpretá-los como Unicode).
Surpreendentemente, a última coluna é inteiramente uniforme. Por isso, na compactação, podemos executar uma mudança de direitos nos dados. Isso garante que todos os códigos sejam ASCII de 7 bits. Na expansão, simplesmente multiplicamos por 65 * 2 = 130 em vez de 65.
A primeira coluna também é totalmente uniforme. Portanto, podemos adicionar 1 a cada elemento (32 a cada byte) sempre que necessário, para evitar qualquer caractere de controle. O 1 indesejado é removido usando a máscara 10001100110011 = 9011 em vez de 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
Embora eu use 15 bytes para a tabela, eu realmente só uso 6 bits de cada byte, que é um total de 90 bits. De fato, existem apenas 36 valores possíveis para cada byte, ou seja, 2,22E23 de possibilidades no total. Isso caberia em 77 bits de entropia.
Rev 2, 58 bytes, usando a abordagem incremental de Randomra
i=0
'UPEIP@bPHPBETTEPRADT'.bytes{|e|puts "%x"%i+=e*65&819}
Finalmente, algo mais curto que a solução ingênua. A abordagem incremental de Randomra, com o método bytepacking de Rev 1.
Rev 1, 72 bytes, versão em golfe da rev 0
Algumas mudanças foram feitas na linha de base para acomodar uma reordenação do código por razões de golfe, mas ainda assim chegou mais do que a solução ingênua.
i=0
'UPUIYD&!)$&V*).);c+*'.bytes{|e|i+=1;puts "%x"%(i/2*273+(e*65&819))}
As compensações são codificadas em cada caractere da sequência mágica na base 4 no formato BAC
, ou seja, com os 1s representando o símbolo da direita, os 16's representando o símbolo do meio e o símbolo da esquerda na posição 4. Para extraí-los, o código ascii é multiplicado por 65 (binário 1000001) para fornecer e BACBAC
, em seguida, é adicionado com 819 (binário 1100110011) para fornecer .A.B.C
.
Alguns dos códigos ascii têm o conjunto de 7 bits, ou seja, são 64 mais altos que o valor necessário, para evitar caracteres de controle. Como esse bit é removido pela máscara 819, isso é inconseqüente, exceto quando o valor de C
é 3, o que causa uma transição. Isso deve ser corrigido em um único local (em vez de g
precisarmos usá-lo c
).
Rev 0, versão ungolfed
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}
Resultado
111
121
222
423
433
433
455
465
665
675
677
778
888
998
a99
aa9
abb
abc
bbc
ccc
Explicação
Da solução a seguir, subtraio a linha de base, fornecendo o deslocamento que armazeno como dados. A linha de base é regenerada como um número hexadecimal no código por i/2*273
(273 decimal = 111 hex.)
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