ロスレス英語テキスト圧縮チャレンジ[終了]


12

チャレンジ:

あなたの挑戦(受け入れることを選択した場合)は、ここにある5MBの「ウィリアムシェークスピアの全集」を圧縮および解凍することです:http : //www.gutenberg.org/cache/epub/100/pg100.txt

(MD5: a810f89e9f8e213aebd06b9f8c5157d8

ルール:

  • あなたはしなければならない介して入力を取るSTDIN経由して出力STDOUT ...
  • ...そして、入力に同一の解凍結果を提供する必要あります。
    • (これは、上記と同じ MD5を取得できなければならないということです。)cat inpt.txt | ./cmprss | ./dcmpress | md5
    • (経由するものSTDERRはすべて破棄されます。)
  • 合計ソースコードには2048文字未満を使用する必要あります。
    • (これはコードゴルフではありません。ソースコードの長さに基づいて得点をているわけではありません。これ物事を有限に保つための単なるルールでした。)
    • (分割した場合は、すべてのソースコードを連結した長さを取ります。)
  • 君は 必要ありますすぎて(理論上)のプロセスと同様のプレーンテキスト入力にできること。
    • (例えば、提供されたシェークスピアのみを出力できるメカニズムをハードコーディングする入力は受け入れられません。)
    • (他の文書の圧縮サイズは無関係です-圧縮解除された結果が代替入力と同一である場合。)
  • あなた言語のいずれかを選択(複数可)を使用します。
    • (例:を使用して圧縮しawkたり、を使用して解凍したりすることをお気軽にjava
  • あなた下さい二つの別々のプログラムを書くかのように「スイッチ」の何らかの形でそれらを結合します。
    • (圧縮モードと解凍モードの両方を呼び出す方法の明確なデモが必要です)
  • 外部コマンド使用できません(例:exec())。
    • (シェル言語を使用している場合-申し訳ありません。ビルトインで間に合わせる必要があります。共有と楽しみのために「受け入れられない」答えを投稿することはできますが、判断はできません! )
  • データを圧縮することを目的とする組み込み関数またはライブラリが提供する関数を使用することはできません(たとえば、gzなど)
    • (エンコードの変更は、このコンテキストでは圧縮とは見なされません。ここでは、何らかの裁量が適用される場合があります。提出物でのソリューションの許容性については、お気軽に議論してください。)
  • 参加することを選んだら、楽しんでみてください!

すべての良い競争には、勝利という客観的な定義があります。エルゴ:

  • すべてのルールが順守されている場合、最小の圧縮出力(STDOUTバイト単位)ます。
    • (を介して出力を報告してください./cmprss | wc -c
  • 抽選(同一の出力サイズ)の場合、最も多くのコミュニティが投票します。
  • 2回目の抽選(同一コミュニティのアップ投票)のイベントでは、優雅さと純粋な天才の完全に主観的な検査に基づいて勝者を選びます。 ;-)

提出方法:

このテンプレートを使用してエントリをフォーマットしてください:

<language>, <compressed_size>
-----------------------------

<description>  (Detail is encouraged!)

    <CODE...
    ...>

<run instructions>

読者と投稿者にコメントを通じて会話することをお勧めします-codegolf.stackを通じて人々が学び、より良いプログラマになるための本当の機会があると信じています。

受賞:

私はすぐに休暇を取ります。今後数週間にわたって提出物を監視するかもしれないし(しないかもしれません)、9月19日に締めくくりに挑戦します。これが、人々が考え、提出する良い機会を提供すること、そして技術とアイデアを積極的に共有することを願っています。

(読者または提出者として)参加して何か新しいことを学んだ場合は、励ましのコメントを残してください。


1
これにタグを付ける必要がありcode-challengeます。
kirbyfan64sos

1
入力を関数の引数として使用できますか?たとえば、JavaScriptなどの言語のソリューションは、コマンドラインAFAIKから実行できませんでした。私の場合、ブラウザで実行する方が簡単です。
ETHproductions

1
なぜテンプレートなのか?それに依存するスタックスニペットを作成しますか?
ピーターテイラー

2
コードサイズの制限がない場合、0バイトを印刷する圧縮プログラムと、シェイクスピアの作品全体を印刷するためにハードコードされた解凍プログラムを書くのを妨げるものは何ですか?
リン

4
@Maurisが指摘した問題を解決するために、コードは理論的に他の入力と連携する必要があるというルールを追加できます。
kirbyfan64sos

回答:


5

Perl 5、3651284

単純な単語ベースの辞書スキームです。コーパスの単語頻度を分析し、それを使用して、単語ごとに1バイトまたは2バイトのオーバーヘッドを使用するかどうかを決定します。コーパスに表示されないため、バイト\ 0および\ 1に2つの特殊記号を使用します。使用できるシンボルは他にもたくさんあります。これは行われませんでした。ハフマンエンコーディングやジャズは一切行いません。

圧縮スクリプトshakespeare.pl:

use strict;
use warnings;
use bytes;

my $text = join "", <>;
my @words = split/([^a-zA-Z0-9]+)/, $text;


my %charfreq;
for( my $i = 0; $i<length($text); ++$i ) {
    $charfreq{ substr($text, $i, 1) }++
}
for my $i ( 0..255 ) {
    my $c = chr($i);
    my $cnt = $charfreq{$c} // 0;
}



my %word_freq;
foreach my $word ( @words ) {
    $word_freq{ $word }++;
}


my $cnt = 0;
my ( @dict, %rdict );
foreach my $word ( sort { $word_freq{$b} <=> $word_freq{$a} || $b cmp $a } keys %word_freq ) {
    last if $word_freq{ $word } == 1; 


    my $repl_length = $cnt < 127 ? 2 : 3;
    if( length( $word ) > $repl_length ) {
        push @dict, $word;
        $rdict{ $word } = $cnt;
        $cnt++;
    }
}


foreach my $index ( 0..$
    print "$dict[$index]\0";
}
print "\1";


foreach my $word ( @words ) {
    my $index = $rdict{ $word };
    if ( defined $index && $index <= 127 ) {
        print "\0" . chr( $index );
    } elsif ( defined $index ) {
        my $byte1 = $index & 127;
        my $byte2 = $index >> 7;
        print "\1" . chr( $byte2 ) . chr( $byte1 );
    } else {
        print $word;
    }
}

解凍スクリプトdeshakespeare.pl:

use strict;
use warnings;
use bytes;

local $/;
my $compressed = <>;
my $text = $compressed;
$text =~ s/^.+?\x{1}//ms;
my $dictionary = $compressed;
$dictionary =~ s/\x{1}.*$//ms;


my $cnt = 0;
my @dict;
foreach my $word ( split "\0", $dictionary ) {

    push @dict, $word;
}


my @words = split /(\x{0}.|\x{1}..)/ms, $text;
foreach my $word ( @words ) {
    if( $word =~ /^\x{0}(.)/ms ) {
        print $dict[ ord( $1 ) ];
    } elsif( $word =~ /^\x{1}(.)(.)/ms ) {
        my $byte1 = ord( $1 );
        my $byte2 = ord( $2 );
        my $index = ( $byte1 << 7 ) + $byte2;
        print $dict[ $index ];
    } else {
        print $word;
    }
}

次を使用して実行:

perl shakespeare.pl < pg100.txt >pg100.txt.compressed
perl deshakespeare.pl <pg100.txt.compressed >pg100.txt.restored
diff pg100.txt pg100.txt.restored
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.