それぞれのx最大値mがわかっているステートレスデコーダーを元の整数にデコードできるように、正の整数をビットにコンパクトにコード化したいx。ハフマン符号化の場合のように、符号化の連結を一意に復号化することが可能でなければならない。
[上記の紹介は残りの動機付けとなりますが、正式な定義の一部ではありません]
表記:負でない整数の場合i、バイナリでn(i)表すのiに必要なビット数とします。それは次のkような負でない最小の整数ですi>>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 ..
およびに対してF(x,m)定義された関数が必要です。出力には ' 'または ' 'の文字列があり、次のプロパティがあります。0<xx<=m01
F(x,m)2*n(x)またはの2*n(m)-1どちらか短い方の長さです。- その場合
x<y:F(x,m)より長くないF(y,m);F(x,m)そしてF(y,m)、長さのある位置で異なりますF(x,m)。- そのような最初の位置に
0インがありF(x,m)ます。
- 特定の
mプロパティ1と2が最大でF(x,m)すべての正に対して一意に定義されていない場合、長さが一致しない最小のものに対して、他の受け入れ可能なエンコーディングよりも長いエンコーディングを拒否します。xmF(x,m)x
注:上記の、暗黙的には0<x、0<y、0<m、x<=m、およびy<=m、その結果F(x,m)とF(y,m)定義されます。
上記の制約と最大9桁の10進数xをm満たしF(x,m)、上記の規則と一致する出力を行うことが最短のプログラムに求められます。次のCフレームワーク(または他の言語では同等のもの)はカウントされません。
#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
コメント:プロパティ1は、エンコードされた長さを積極的に制限します。プロパティ2は、明確なデコードが可能であることを形式化し、エンコードを正規化します。私は(証明なしで)これはFwhen の出力m+1が2の累乗を一意に定義するのFに十分であり、プロパティ3はother を一意に定義するのに十分であることを主張しますm。
ここに部分的な表があります(手作り、投稿された最初のバージョンはエラーで謎でした、申し訳ありません):
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、デコードが不可能になることです。提案されたコーディングを使用すると、いくつかの出力の連結を一意にデコードできます(m動的に変化する最大値を含む)。私はそれを明確にしようとしました。