program RLEPascal;
{$mode objfpc} { modern Free Pascal mode }
uses
SysUtils;
(* ---------------------------------------------------------
Compress: turn "aaabbcccc" into "a3b2c4"
This is run-length encoding (RLE)
--------------------------------------------------------- *)
function Compress(const s: AnsiString): AnsiString;
var
outStr: AnsiString; // Result string
count: Integer; // Count of repeated characters
i: Integer;
begin
if s = '' then
begin
Result := ''; // Edge case: empty string
Exit;
end;
outStr := '';
count := 1;
// Start from index 2 and compare with previous character
for i := 2 to Length(s) + 1 do
begin
// If still repeating the same character, increase count
if (i <= Length(s)) and (s[i] = s[i - 1]) then
Inc(count)
else
begin
// Character changed OR reached end of string
outStr += s[i - 1]; // Add the character
outStr += IntToStr(count); // Add how many times it repeated
count := 1; // Reset counter
end;
end;
Result := outStr;
end;
(* ---------------------------------------------------------
Decompress: turn "a3b2c4" into "aaabbcccc"
Reads a letter, then reads digits, expands them.
--------------------------------------------------------- *)
function Decompress(const s: AnsiString): AnsiString;
var
outStr: AnsiString; // Result string
currentChar: Char; // The character being processed
number: AnsiString; // Digits representing the count
i, k, count: Integer;
c: Char;
begin
outStr := '';
currentChar := #0;
number := '';
for i := 1 to Length(s) do
begin
c := s[i];
if c in ['A'..'Z', 'a'..'z'] then // Found a letter
begin
// If we already have a previous letter + number, expand it
if (currentChar <> #0) and (number <> '') then
begin
count := StrToInt(number);
for k := 1 to count do
outStr += currentChar;
end;
currentChar := c; // Start new character
number := ''; // Reset number buffer
end
else if c in ['0'..'9'] then // Found a digit
begin
number += c; // Build multi-digit number
end;
end;
// Handle the last character + number pair
if (currentChar <> #0) and (number <> '') then
begin
count := StrToInt(number);
for k := 1 to count do
outStr += currentChar;
end;
Result := outStr;
end;
var
s, c, d: AnsiString;
begin
s := 'wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww';
c := Compress(s);
d := Decompress(c);
WriteLn('Original: ', s);
WriteLn('Compressed: ', c);
WriteLn('Decompressed: ', d);
end.
(*
run:
Original: wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww
Compressed: w12b1w10b3w6c4w12
Decompressed: wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww
*)