RosettaCodeData/Task/LZW-compression/Seed7/lzw-compression.seed7
2016-12-05 22:15:40 +01:00

75 lines
2 KiB
Text

$ include "seed7_05.s7i";
const func string: lzwCompress (in string: uncompressed) is func
result
var string: compressed is "";
local
var char: ch is ' ';
var hash [string] char: mydict is (hash [string] char).value;
var string: buffer is "";
var string: xstr is "";
begin
for ch range chr(0) to chr(255) do
mydict @:= [str(ch)] ch;
end for;
for ch range uncompressed do
xstr := buffer & str(ch);
if xstr in mydict then
buffer &:= str(ch)
else
compressed &:= str(mydict[buffer]);
mydict @:= [xstr] chr(length(mydict));
buffer := str(ch);
end if;
end for;
if buffer <> "" then
compressed &:= str(mydict[buffer]);
end if;
end func;
const func string: lzwDecompress (in string: compressed) is func
result
var string: uncompressed is "";
local
var char: ch is ' ';
var hash [char] string: mydict is (hash [char] string).value;
var string: buffer is "";
var string: current is "";
var string: chain is "";
begin
for ch range chr(0) to chr(255) do
mydict @:= [ch] str(ch);
end for;
for ch range compressed do
if buffer = "" then
buffer := mydict[ch];
uncompressed &:= buffer;
elsif ch <= chr(255) then
current := mydict[ch];
uncompressed &:= current;
chain := buffer & current;
mydict @:= [chr(length(mydict))] chain;
buffer := current;
else
if ch in mydict then
chain := mydict[ch];
else
chain := buffer & str(buffer[1]);
end if;
uncompressed &:= chain;
mydict @:= [chr(length(mydict))] buffer & str(chain[1]);
buffer := chain;
end if;
end for;
end func;
const proc: main is func
local
var string: compressed is "";
var string: uncompressed is "";
begin
compressed := lzwCompress("TOBEORNOTTOBEORTOBEORNOT");
writeln(literal(compressed));
uncompressed := lzwDecompress(compressed);
writeln(uncompressed);
end func;