How to write an equivalent to PHP count_chars(string $string, int $mode = 0): array|string function in Pascal

1 Answer

0 votes
program CharCounter;

const
  ASCII_RANGE = 256;  // Total number of ASCII characters 

type
  TFreqArray = array[0..ASCII_RANGE-1] of Integer; { Array to hold frequency counts }

{-------------------------------------------------------------}
{ CountChars: Counts character frequencies in 'input' string. }
{ Depending on 'mode', it either fills the frequency array or }
{ builds a string of used/unused characters.                  }
{ Mode 0,1,2 → fill freq array                                }
{ Mode 3 → build string of used characters                    }
{ Mode 4 → build string of unused characters                  }
{-------------------------------------------------------------}
procedure CountChars(input: string; mode: Integer; var freq: TFreqArray; var outStr: string);
var
  i: Integer;
begin
  // Reset frequencies 
  for i := 0 to ASCII_RANGE-1 do
    freq[i] := 0;

  // Count frequencies for each character in the input string 
  for i := 1 to Length(input) do
    Inc(freq[Ord(input[i])]);

  outStr := '';  { Clear output string }

  if mode = 3 then
  begin
    // Mode 3: Build string of used printable characters 
    for i := 32 to 126 do
      if freq[i] > 0 then
        outStr := outStr + Chr(i);
  end
  else if mode = 4 then
  begin
    // Mode 4: Build string of unused printable characters 
    for i := 32 to 126 do
      if freq[i] = 0 then
        outStr := outStr + Chr(i);
  end;
end;

{-------------------------------------------------------------}
{ PrintArray: Prints characters and their frequencies.        }
{ mode = 0 → all characters                                   }
{ mode = 1 → only used characters                             }
{ mode = 2 → only unused characters                           }
{ printableOnly = True → restrict to ASCII 32–126             }
{-------------------------------------------------------------}
procedure PrintArray(const freq: TFreqArray; mode: Integer; printableOnly: Boolean);
var
  i, startIdx, endIdx: Integer;
  condition: Boolean;
begin
  // Decide whether to print all ASCII or only printable characters 
  if printableOnly then
  begin
    startIdx := 32;
    endIdx := 126;
  end
  else
  begin
    startIdx := 0;
    endIdx := ASCII_RANGE-1;
  end;

  // Loop through chosen range 
  for i := startIdx to endIdx do
  begin
    condition := True;
    if (mode = 1) and (freq[i] <= 0) then condition := False; { used only }
    if (mode = 2) and (freq[i] <> 0) then condition := False; { unused only }

    // Print character, ASCII code, and frequency if condition met 
    if condition then
      WriteLn('''', Chr(i), ''' (', i, '): ', freq[i]);
  end;
end;

{-------------------------------------------------------------}
{ Main program: Demonstrates the four modes of character count}
{-------------------------------------------------------------}
var
  text: string;       // Input text to analyze 
  freq: TFreqArray;   // Frequency array 
  buffer: string;     // Output string for modes 3 and 4 

begin
  text := 'It''s the perfect time to start';

  // Mode 1: Only used characters and their frequencies 
  WriteLn('Mode 1: Used characters only');
  CountChars(text, 1, freq, buffer);
  PrintArray(freq, 1, True);

  // Mode 2: Unused characters 
  WriteLn;
  WriteLn('Mode 2: Unused characters');
  CountChars(text, 2, freq, buffer);
  PrintArray(freq, 2, True);

  // Mode 3: String of used characters 
  WriteLn;
  Write('Mode 3: String of used characters: ');
  CountChars(text, 3, freq, buffer);
  WriteLn(buffer);

  // Mode 4: String of unused characters 
  WriteLn;
  Write('Mode 4: String of unused characters: ');
  CountChars(text, 4, freq, buffer);
  WriteLn(buffer);
end.


(*
run:

Output:

Mode 1: Used characters only
' ' (32): 5
''' (39): 1
'I' (73): 1
'a' (97): 1
'c' (99): 1
'e' (101): 4
'f' (102): 1
'h' (104): 1
'i' (105): 1
'm' (109): 1
'o' (111): 1
'p' (112): 1
'r' (114): 2
's' (115): 2
't' (116): 7

Mode 2: Unused characters
'!' (33): 0
'"' (34): 0
'#' (35): 0
'$' (36): 0
'%' (37): 0
'&' (38): 0
'(' (40): 0
')' (41): 0
'*' (42): 0
'+' (43): 0
',' (44): 0
'-' (45): 0
'.' (46): 0
'/' (47): 0
'0' (48): 0
'1' (49): 0
'2' (50): 0
'3' (51): 0
'4' (52): 0
'5' (53): 0
'6' (54): 0
'7' (55): 0
'8' (56): 0
'9' (57): 0
':' (58): 0
';' (59): 0
'<' (60): 0
'=' (61): 0
'>' (62): 0
'?' (63): 0
'@' (64): 0
'A' (65): 0
'B' (66): 0
'C' (67): 0
'D' (68): 0
'E' (69): 0
'F' (70): 0
'G' (71): 0
'H' (72): 0
'J' (74): 0
'K' (75): 0
'L' (76): 0
'M' (77): 0
'N' (78): 0
'O' (79): 0
'P' (80): 0
'Q' (81): 0
'R' (82): 0
'S' (83): 0
'T' (84): 0
'U' (85): 0
'V' (86): 0
'W' (87): 0
'X' (88): 0
'Y' (89): 0
'Z' (90): 0
'[' (91): 0
'\' (92): 0
']' (93): 0
'^' (94): 0
'_' (95): 0
'`' (96): 0
'b' (98): 0
'd' (100): 0
'g' (103): 0
'j' (106): 0
'k' (107): 0
'l' (108): 0
'n' (110): 0
'q' (113): 0
'u' (117): 0
'v' (118): 0
'w' (119): 0
'x' (120): 0
'y' (121): 0
'z' (122): 0
'{' (123): 0
'|' (124): 0
'}' (125): 0
'~' (126): 0

Mode 3: String of used characters:  'Iacefhimoprst

Mode 4: String of unused characters: !"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHJKLMNOPQRSTUVWXYZ[\]^_`bdgjklnquvwxyz{|}~

*)

 



answered 3 hours ago by avibootz
edited 3 hours ago by avibootz
...