Сжатие текста с потерями


9

Фон

Из 256 возможных символов, которые может представлять байт, только некоторые из них используются в большинстве случаев. Не могли бы мы каким-то образом воспользоваться этим и уменьшить наши текстовые файлы, исключив необходимость использования редко используемых букв?

Многие буквы не добавляют никакого значения в большинстве ситуаций и могут быть заменены более распространенными буквами. Например, строчные буквы «L», заглавные «I» и число «1» в большинстве ситуаций выглядят почти одинаково, поэтому их можно объединить.

Существует небольшая потребность в заглавных буквах, поэтому их можно обойтись. Программа распаковки / отображения может даже автоматически использовать заглавные буквы в каждом предложении, общих именах и т. Д.

правила

Записи будут оцениваться по:

  • коэффициент сжатия
  • удобочитаемость после распаковки

Записи будут проверены на соответствие текстовой версии этой статьи: http://en.wikipedia.org/wiki/Babbage и случайно выбранной статье BBC News .

Дополнительные оценки будут начислены за; сохранение любой разметки, украшение после декомпрессии (например, использование заглавных букв и т. д.).

Языки

  • Все, что вам нравится, но должно быть легко скомпилировано (или интерпретировано) в базовом * nix-боксе.

Так что PowerShell вышел? Облом.
Джои

1
Хаскелл:main = interact (\x -> take 90 x ++ " yada yada yada")
Джои Адамс,

1
Отметим также, что «читаемость после декомпрессии» является довольно субъективным критерием.
Джои

Особенно в Unix-Box нам нужны различия прописных и строчных букв. :) И найти начало отправлено. Нетривиально, если вы. Использует сокращение.! :)
пользователь неизвестен

Мы хотим сжать алфавит или текст? :) L = l = 1 сжимает символы, необходимые для представления наших мыслей. Но "one apple" = "1 apl" сжимает текст.
anemgyenge

Ответы:


11

Perl

Очень неэффективно и имеет плохие показатели. Требуется /usr/share/dict/words.

компрессор

#!/usr/bin/perl

$M = 2;
$N = 1;
$Min = 3;
$Max = 8;

while (<>) {
  for (split /\s+/) {
    s/[^a-z]//i;
    ($p) = m/([^a-z]*)$/;
    $_ = lc $_;
    $l = (length $_) - (length $p);
    s/^and$/A/;
    s/^he$/H/;
    s/^in$/I/;
    s/^of$/O/;
    s/^you$/U/;
    s/^the$/Z/;
    if (length $_ >= $Min) {
      if (length $_ <= $Max) {
        s/ed/D/g;
        s/ing\b/N/g;
        s/er/R/g;
        s/'s/S/g;
        s/th/T/g;
        s/[aeo]{1,2}//g;
        $_ .= $l;
      } else {
        s/^(.{$M})(.+)(\w{$N})$/$1.(length$2).$3/e;
      }
    }
    $a .= $_ . $p . ' ';
  }
}
print $a;

декомпрессор

#!/usr/bin/perl

$M = 2;
$N = 1;

open D, '/usr/share/dict/words';
chomp, push @W, $_ while <D>;
close D;

while (<>) {
  for (split /\s+/) {
    ($_, $p) = m/^(.+)([^a-z]*)$/;
    s/^A$/and/;
    s/^H$/he/;
    s/^I$/in/;
    s/^O$/of/;
    s/^U$/you/;
    s/^Z$/the/;
    if ($_ =~ m/^(\w{$M})(\d+)(\w{$N})$/) {
      $r = '^' . quotemeta($1) . ('\w' x $2) . quotemeta($3) . '$';
      ($_) = (grep /$r/, @W);
      $_ .= $4;
    } else {
      ($_, $l) = m/^(.+)(\d+)$/;
      s/D/ed/g;
      s/N/ing/g;
      s/R/er/g;
      s/S/'s/g;
      s/T/th/g;
      $r = '[aeo]{0,2}';
      for $y(split //) { $r .= (quotemeta $y) . '[aiueo]{0,2}' }
      ($_) = (grep /^(?=[a-z]{$l})$r$/, @W);
    }
    $a .= $_ . $p . ' ';
  }
}
print $a;

3

Perl, 0 символов

Степень сжатия бесконечности, хотя и не настолько читаемая после декомпрессии, поэтому она потеряет некоторые отметки.


2

Баш, 5 символов

Моя ленивая запись, которая только может победить:

bzip2

Без потерь, поэтому он отлично сохраняет читаемость и получает все дополнительные оценки! Коэффициент сжатия в HTML-коде «Бэббидж» составляет 4,79х (от 153804 до 32084 байт).


Каким-то образом я знал, что это будет с этим испытанием ;-)
Joey

Это будет трудно победить.
Lowjacker

Хах! Я побил его и по длине, и по степени сжатия;)
Ry-

2
хз, еще короче и лучше соотношение :)
OneOfOne
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.