Anonymous user
Run-length encoding: Difference between revisions
→{{header|Perl}}: add advanced version that fully complies with the spec of the C solution
(→{{header|Perl}}: clean up & modernize) |
(→{{header|Perl}}: add advanced version that fully complies with the spec of the C solution) |
||
Line 2,434:
=={{header|Perl}}==
Simple version using ASCII numerals as
<lang perl>sub encode {
Line 2,444:
}</lang>
<lang perl>sub encode {
Line 2,453:
shift =~ s/(.)(.)/$2 x unpack("C", $1)/grse;
}</lang>
Further modified version that supports compact representation of longer non-repeating substrings, just like the [[#C|C solution]] (so should be fully compatible with that solution for both encoding and decoding):
<lang perl>sub encode {
my $str = shift;
my $ret = "";
my $nonrep = "";
while ($str =~ m/(.)\1{0,127}|\z/gs) {
my $len = length($&);
if (length($nonrep) && (length($nonrep) == 127 || $len != 1)) {
$ret .= pack("C", 128 + length($nonrep)) . $nonrep;
$nonrep = "";
}
if ($len == 1) { $nonrep .= $1 }
elsif ($len > 1) { $ret .= pack("C", $len) . $1 }
}
return $ret;
}
sub decode {
my $str = shift;
my $ret = "";
for (my $i = 0; $i < length($str);) {
my $len = unpack("C", substr($str, $i, 1));
if ($len <= 128) {
$ret .= substr($str, $i + 1, 1) x $len;
$i += 2;
}
else {
$ret .= substr($str, $i + 1, $len - 128);
$i += 1 + $len - 128;
}
}
return $ret;
}</lang>
Demonstration of the third version:
<lang perl>use Data::Dump qw(dd);
dd my $str = "XXXXXABCDEFGHIoooooooooooooooooooooooooAAAAAA";
dd my $enc = encode($str);
dd decode($enc);</lang>
{{out}}
<pre>
"XXXXXABCDEFGHIoooooooooooooooooooooooooAAAAAA"
"\5X\x89ABCDEFGHI\31o\6A"
"XXXXXABCDEFGHIoooooooooooooooooooooooooAAAAAA"
</pre>
=={{header|Perl 6}}==
|