7

规则

  1. 你的程序必须有两种模式:编码解码
  2. 编码时:

    1. 你的程序必须输入一些人类可读的Latin1文本,大概是英语。
      • 忽略标点符号也没关系。
      • 您只需要担心实际的英语单词,而不是 L337。
      • 任何重音字母都可以转换为简单的 ASCII。
      • 您可以选择处理数字的方式。
      • 123
        • 一二三
        • 一百二十三
        • 123
        • 1 2 3
      • 一百二十三
        • 一二三
        • 一百二十三
        • 123
        • 1 2 3
    2. 您的程序必须输出一条可以表示为的消息

      • 范围内的 140 个代码点U+0000–<code>U+10FFFF

        排除非字符:

        • U+FFFE
        • U+FFFF
        • U+nFFFE,其中–<code>10 十六进制U+nFFFFn1
        • U+FDD0–<code>U+FDEF
        • U+D800–<code>U+DFFF(代理代码点)。

    它可以以您选择的任何合理编码输出;GNUiconv支持的任何编码都将被认为是合理的,您的平台本机编码或语言环境编码可能是一个不错的选择。

  3. 解码时:

    1. 您的程序应将编码模式的输出作为输入。
    2. 文本输出应该是输入文本的近似值。
      • 越接近原文越好。
      • 不需要任何标点符号。
    3. 输出文本应该是人类可读的,同样可能是英语。

      • 可以是 L337,也可以是大声笑。
    4. 除了上面指定的输出之外,解码过程可能无法访问编码过程的任何其他输出;也就是说,您不能将文本上传到某处并输出 URL 以供解码过程下载,或者任何类似的愚蠢行为。
  4. 为了用户界面的一致性,您的程序必须表现如下:
    1. 您的程序必须是可以在具有适当解释器的平台上设置为可执行的脚本,或者是可以编译为可执行文件的程序。
    2. 您的程序必须将encodedecode设置模式作为其第一个参数。
    3. 您的程序必须至少以下列方式之一接受输入:
      • 从标准输入获取输入并在标准输出上产生输出。
        • my-program encode <input.txt >output.utf
        • my-program decode <output.utf >output.txt
      • 从第二个参数命名的文件中获取输入,并在第三个参数命名的文件中产生输出。
        • my-program encode input.txt output.utf
        • my-program decode output.utf output.txt
  5. 对于您的解决方案,请发布:
    1. 您的完整代码和/或在其他地方托管的指向它的链接(如果它很长,或者需要很多文件来编译,或其他)。
    2. 如果代码不是很明显,或者代码很长并且人们会对摘要感兴趣,则说明它是如何工作的。
    3. 示例文本,包含原始文本、压缩后的文本和解码的文本。
    4. 如果您正在建立其他人的想法,请归因于他们。尝试对别人的想法进行提炼是可以的,但你必须归因于他们。

这些规则是Twitter 图像编码挑战规则的变体。

4

4 回答 4

3

不确定我是否有时间/精力来跟进实际代码,但这是我的想法:

  • 任何特定长度下的任意 LATIN 1 字符串都可以简单地编码(甚至不压缩),而不会丢失 140 个字符。天真的估计是 280 个字符,尽管由于竞赛规则中的代码点限制,它可能比这短一点。
  • 稍长于上述长度的字符串(假设在 280 到 500 个字符之间)很可能使用标准压缩技术收缩成足够短的字符串以允许上述编码。

任何比这更长的时间,我们就会开始丢失文本中的信息。因此,执行以下步骤的最小数量,以将字符串减少到可以使用上述方法压缩/编码的长度。此外,如果仅在子字符串上执行这些替换会使它足够短(我可能会向后遍历字符串),请不要在整个字符串上执行这些替换。

  1. 将 127 以上的所有 LATIN 1 字符(主要是重音字母和时髦符号)替换为在非重音字母字符中最接近的等价物,或者可能使用通用符号替换,如“#”
  2. 用等效的小写形式替换所有大写字母
  3. 用空格替换所有非字母数字(任何剩余的符号或标点符号)
  4. 用 0 替换所有数字

好的,所以现在我们已经消除了尽可能多的多余字符。现在我们要做一些更显着的减少:

  1. 将所有双字母(气球)替换为单个字母(巴隆)。看起来很奇怪,但仍然希望读者能够理解。
  2. 用较短的等价物替换其他常见的字母组合(CK 与 K,WR 与 R 等)

好的,这就是我们所能做到的,让文本可读。除此之外,让我们看看我们是否可以想出一种方法,使文本原始文本相似,即使它最终无法辨认(再次,从字符串末尾一次执行一个字符,并在它足够短):

  1. 将所有元音 (aeiouy) 替换为
  2. 将所有“高”字母 (bdfhklt) 替换为 l
  3. 将所有“短”字母 (cmnrsvwxz) 替换为 n
  4. 将所有“悬挂”字母 (gjpq) 替换为 p

这应该给我们留下一个由 5 个可能值(a、l、n、p 和空格)组成的字符串,这应该允许我们编码相当长的字符串。

除此之外,我们只需要截断。

我能想到的唯一其他技术是对常用单词或字母组进行基于字典的编码。这可能会给我们一些正确句子的好处,但可能不会为任意字符串带来好处。

于 2009-06-22T14:53:23.867 回答
1

这是我实际英语的变体。

每个代码点都有 1100000 种可能的状态。嗯,这是很大的空间。

因此,我们提取所有原始文本并从中获取 Wordnet 同义词集。数字被转换成英文名称(“四十二”)。1,1M 个状态将允许我们保存同义词集 ID(可以在 0 到 82114 之间)、同义词集内的位置(我想大约 10 个变体)和同义词集类型(这是四种之一 - 名词、动词、形容词、副词) . 我们甚至可能有足够的空间来存储单词的原始形式(如动词时态 id)。

解码器只是将同义词提供给 Wordnet 并检索相应的单词。

源文本:

A white dwarf is a small star composed mostly of electron-degenerate matter. Because a
white dwarf's mass is comparable to that of the Sun and its volume is comparable to that 
of the Earth, it is very dense.

变成:

A white dwarf be small star composed mostly electron degenerate matter because white
dwarf mass be comparable sun IT volume be comparable earth IT be very dense

(使用在线 Wordnet测试)。此“代码”应占用 27 个代码点。当然,所有像“lol”和“L33T”这样的“胡言乱语”都将永远消失。

于 2009-06-25T16:51:32.017 回答
0

这是一个简单的例子,它接受一个输入文件并删除任何非单词字符。

#! perl
use strict;
use warnings;
use 5.010;


use Getopt::Long;
use Pod::Usage;
use autodie;

my %opts = (
  infile  => '-',
  outfile => '-',
);
GetOptions (
  'encode|e'    => \$opts{encode},
  'decode|d'    => \$opts{decode},
  'infile|i=s'  => \$opts{infile},
  'outfile|o=s' => \$opts{outfile},
  'help|h'      => \&help,
  'man|m'       => \&man,
);

unless(
  # exactly one of these should be set
  $opts{encode} xor $opts{decode}
){
  help();
}


{
  my $infile;
  if( $opts{infile} ~~ ['-', '&0'] ){
    $infile = *STDIN{IO};
  }else{
    open $infile, '<', $opts{infile};
  }

  my $outfile;
  if( $opts{outfile} ~~ ['-', '&1'] ){
    $outfile = *STDOUT{IO};
  }elsif( $opts{outfile} ~~ '&2' ){
    $outfile = *STDERR{IO};
  }else{
    open $outfile, '>', $opts{outfile};
  }

  if( $opts{decode} ){
    while( my $line = <$infile> ){
      chomp $line;

      say {$outfile} $line;
    }
  }elsif( $opts{encode} ){
    while( my $line = <$infile> ){
      chomp $line;

      $line =~ s/[\W_]+/ /g;

      say {$outfile} $line;
    }
  }else{
    die 'How did I get here?';
  }
}

sub help{
  pod2usage();
}
sub man{
  pod2usage(1);
}
__END__

=head1 NAME

sample.pl - Using GetOpt::Long and Pod::Usage

=head1 SYNOPSIS

sample.pl [options] [file ...]

 Options:
   --help     -h      brief help message
   --man      -m      full documentation
   --encode   -e      encode text
   --decode   -d      decode text
   --infile   -i      input  filename
   --outfile  -o      output filename

=head1 OPTIONS

=over 8

=item B<--help>

Print a brief help message and exits.

=item B<--man>

Prints the manual page and exits.

=item B<--encode>

Removes any character other than /\w/.

=item B<--decode>

Just reads from one file, and writes to the other.

=item B<--infile>

Input filename. If this is '-' or '&0', then read from STDIN instead.
If you use '&0', you must pass it in with quotes.

=item B<--outfile>

Output filename. If this is '-' or '&1', then write to STDOUT instead.
If this is '&2', then write to STDERR instead.
If you use '&1' or '&2', you must pass it in with quotes.

=back

=head1 DESCRIPTION

B<This program> will read the given input file(s) and do something
useful with the contents thereof.

=cut
echo 你好,这是一些文字 | perl 示例.pl -e
你好这是一些文字
于 2009-06-22T17:06:45.700 回答
0

PAQ8O10T << FTW

于 2009-06-20T18:34:57.043 回答