Eu quero codificar compactamente números inteiros positivos x
em bits, de uma maneira que permita a decodificação de volta nos números inteiros originais para um decodificador sem estado, sabendo o valor máximo m
de cada um x
; deve ser possível decodificar exclusivamente a concatenação de codificações, como é o caso da codificação de Huffman.
[A introdução acima motiva o resto, mas não faz parte da definição formal]
Notação: para qualquer número inteiro não negativo i
, n(i)
seja o número de bits necessário para representar i
em binário; esse é o menor inteiro não negativo de k
tal forma quei>>k == 0
i : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ..
n(i): 0 1 2 2 3 3 3 3 4 4 4 4 4 4 4 4 5 5 5 ..
Eu quero uma função F(x,m)
definida para 0<x
e x<=m
, com saída, uma sequência de ' 0
' ou ' 1
', com estas propriedades:
F(x,m)
tem comprimento menor que2*n(x)
ou2*n(m)-1
, o que for menor.- Se
x<y
então:F(x,m)
não é mais do queF(y,m)
;F(x,m)
eF(y,m)
diferem em alguma posição ao longo deF(x,m)
;- há um
0
naF(x,m)
primeira posição.
- Quando por certas
m
propriedades 1 e 2 não se definir de forma únicaF(x,m)
para todos positivosx
no máximom
, se rejeitar qualquer codificação dando um maisF(x,m)
do que alguns codificação de outro modo aceitável, para a mais pequenax
para que o comprimento não coincidem.
Nota: No exemplo acima, implicitamente, 0<x
, 0<y
, 0<m
, x<=m
, e y<=m
, de modo que F(x,m)
e F(y,m)
são definidos.
É solicitado o programa mais curto que, dado qualquer um x
e m
atendendo às restrições acima e até 9 dígitos decimais, gera uma F(x,m)
consistência com as regras acima. A seguinte estrutura C (ou seu equivalente em outros idiomas) não é contada:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define C(c) putchar((c)?'1':'0') // output '0' or '1'
#define S(s) fputs((s),stdout) // output a string
typedef unsigned long t; // at least 32 bits
void F(t x,t m); // prototype for F
int main(int argc,char *argv[]){
if(argc==3)F((t)atol(argv[1]),(t)atol(argv[2]));
return 0;}
void F(t x,t m) { // counting starts on next line
} // counting ends before this line
Comentário: A propriedade 1 limita agressivamente o comprimento codificado; a propriedade 2 formaliza que a decodificação inequívoca é possível e canoniza a codificação; Afirmo (sem prova) que isso é suficiente para definir exclusivamente a saída de F
quando m+1
é uma potência de dois e que a propriedade 3 é suficiente para definir exclusivamente F
para outra m
.
Aqui está uma tabela parcial (artesanal; a primeira versão postada estava cheia de erros, desculpe):
x : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
F(x,1) : empty
F(x,2) : 0 1
F(x,3) : 0 10 11
F(x,4) : 0 10 110 111
F(x,5) : 0 10 110 1110 1111
F(x,6) : 0 100 101 110 1110 1111
F(x,7) : 0 100 101 1100 1101 1110 1111
F(x,8) : 0 100 101 110 11100 11101 11110 11111
F(x,15) : 0 100 101 11000 11001 11010 11011 111000 111001 111010 111011 111100 111101 111110 111111
11111
, tornando impossível a decodificação. Com a codificação proposta, a concatenação de várias saídas pode ser decodificada exclusivamente (inclusive com a máxima m
alteração dinâmica). Eu tentei esclarecer isso.