Ich möchte positive ganze Zahlen kompakt xin Bits codieren , so dass ein zustandsloser Decoder, der den Maximalwert mvon jedem kennt, wieder in die ursprünglichen ganzen Zahlen decodieren kann x. Es soll möglich sein, die Verkettung von Codierungen eindeutig zu decodieren, wie dies bei der Huffman-Codierung der Fall ist.
[Die obige Einleitung motiviert den Rest, ist aber nicht Teil der formalen Definition]
Notation: Für jede nicht negative ganze Zahl isei n(i)die Anzahl der Bits, die zur Darstellung iin Binärzahlen erforderlich sind . das ist die kleinste nicht negative ganze Zahl, kso dassi>>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 ..
Ich möchte eine Funktion, F(x,m)die für 0<xund x<=mmit der Ausgabe einer Zeichenfolge von ' 0' oder ' 1' definiert ist und folgende Eigenschaften aufweist:
F(x,m)hat eine Länge von weniger als2*n(x)oder2*n(m)-1, je nachdem, welcher Wert kleiner ist.- Wenn
x<ydann:F(x,m)ist nicht länger alsF(y,m);F(x,m)undF(y,m)unterscheiden sich an einer Position über die Länge vonF(x,m);- Es gibt ein
0InF(x,m)an der ersten solchen Position.
- Wenn für bestimmte
mEigenschaften 1 und 2 höchstens nichtF(x,m)für alle positiven Eigenschaften eindeutig definiert sind , lehnen wir jede Codierung ab, die eine längere als eine ansonsten akzeptable Codierung ergibt , für die kleinste, für die die Länge nicht übereinstimmt.xmF(x,m)x
Hinweis: Bei der oben implizit 0<x, 0<y, 0<m, x<=m, und y<=m, so dass F(x,m)und F(y,m)definiert.
Es ist das kürzeste Programm darum gebeten , dass, da jeder xund die mErfüllung die oben genannten Einschränkungen und bis zu 9 Dezimalstellen, gibt eine in F(x,m)Übereinstimmung mit den oben genannten Regeln. Das folgende C-Framework (oder sein Äquivalent in anderen Sprachen) wird nicht gezählt:
#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
Kommentar: Eigenschaft 1 begrenzt die codierte Länge aggressiv. Eigenschaft 2 formalisiert, dass eine eindeutige Decodierung möglich ist, und kanonisiert die Codierung; Ich behaupte (ohne Beweis), dass dies ausreicht, um die Ausgabe von Fwann m+1eine Zweierpotenz eindeutig zu definieren, und dass Eigenschaft 3 ausreicht, um Ffür andere eindeutig zu definieren m.
Hier ist eine Teiltabelle (handgemacht; die erste veröffentlichte Version war voller Fehler, sorry):
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, die Dekodierung unmöglich machen. Mit der vorgeschlagenen Codierung kann die Verkettung mehrerer Ausgänge eindeutig decodiert werden (auch wenn sich das Maximum mdynamisch ändert). Ich habe versucht, das zu klären.