Search code examples
delphiloopsdelphi-7permutationcombinations

Create an Unknown Number of Loops


this is my simple code to generate all possible combinations of a set for example

1,2,3:

  • Display: 123 132 213 231 312 321

i want to create variable number of for loops to let the user determine the length of given string...

does anyone have an idea...

thank's in advance.

type
  TNumber = '0'..'9';

procedure TForm1.Button1Click(Sender: TObject);
var
  Numbers: array[0..3] of TNumber;
  a, b, c, d: Integer;
  s: string;
begin
  Numbers[0] := '1';
  Numbers[1] := '8';
  Numbers[2] := '7';
  Numbers[3] := '2';
  for a := low(Numbers) to High(Numbers) do
    for b := low(Numbers) to High(Numbers) do
      for c := low(Numbers) to High(Numbers) do
        for d := low(Numbers) to High(Numbers) do
        begin
          s := Numbers[a] + Numbers[b] + Numbers[c]  + Numbers[d];
          if
            (Occurrences('1', s) > 1 ) or
            (Occurrences('8', s) > 1 ) or
            (Occurrences('7', s) > 1 ) or
            (Occurrences('2', s) > 1 )
          then
            Continue
          else
            Memo1.Lines.Add(s);
  end;
end;

function TForm1.Occurrences(const Substring, Text: string): Integer;
var
  Offset: Integer;
begin
  Result := 0;
  Offset := PosEx(Substring, Text, 1);
  while Offset <> 0 do
  begin
    Inc(Result);
    Offset := PosEx(Substring, Text, offset + length(Substring));
  end;
end;

end.


Solution

  • Here is some code that produces the output you desire. You'd need to work it around a bit for your needs, but the concept expressed in this recursive solution is the important thing:

    program Permuatations;
    
    {$APPTYPE CONSOLE}
    
    type
      TElements = '1'..'3';
    
    procedure EnumerateCombinations(const Stem: string; Len: Integer);
    var
      i: Integer;
      el: TElements;
      Used: set of TElements;
    begin
      if Len=0 then
        exit;
      Used := [];
      for i := 1 to Length(Stem) do
        Include(Used, Stem[i]);
      for el := low(el) to high(el) do
      begin
        if el in Used then
          continue;
        if Len=1 then
          Writeln(Stem+el)
        else
          EnumerateCombinations(Stem+el, Len-1)
      end;
    end;
    
    procedure Main;
    begin
      EnumerateCombinations('', 1+ord(high(TElements))-ord(low(TElements)));
    end;
    
    begin
      Main;
      Readln;
    end.
    

    Output:

    123
    132
    213
    231
    312
    321
    

    If you change the definition of TElements, for example to '1'..'4' then you will see the 24 possible permutations.