How to resolve the algorithm Permutations by swapping step by step in the Delphi programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Permutations by swapping step by step in the Delphi programming language

Table of Contents

Problem Statement

Generate permutations of n items in which successive permutations differ from each other by the swapping of any two items. Also generate the sign of the permutation which is +1 when the permutation is generated from an even number of swaps from the initial state, and -1 for odd. Show the permutations and signs of three items, in order of generation here. Such data are of use in generating the determinant of a square matrix and any functions created should bear this in mind. Note: The Steinhaus–Johnson–Trotter algorithm generates successive permutations where adjacent items are swapped, but from this discussion adjacency is not a requirement.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Permutations by swapping step by step in the Delphi programming language

Source code in the delphi programming language

{These routines would normally be in a separate library; they are presented here for clarity}


{Permutator based on the Johnson and Trotter algorithm.}
{Which only permutates by swapping a pair of elements at a time}
{object steps through all permutation of array items}
{Zero-Based = True = 0..Permutions-1 False = 1..Permutaions}
{Permutation set on "Create(Size)" or by "Permutations" property}
{Permutation are contained in the array "Indices"}

type TDirection = (drLeftToRight,drRightToLeft);
type TDirArray = array of TDirection;


type TJTPermutator = class(TObject)
 private
  Dir: TDirArray;
  FZeroBased: boolean;
  FBase: integer;
  FPermutations: integer;
  procedure SetZeroBased(const Value: boolean);
  procedure SetPermutations(const Value: integer);
 protected
   FMax: integer;
 public
  NextCount: Integer;
  Indices: TIntegerDynArray;
  constructor Create(Size: integer);
  procedure Reset;
  function Next: boolean;
  property ZeroBased: boolean read FZeroBased write SetZeroBased;
  property Permutations: integer read FPermutations write SetPermutations;
 end;


{==============================================================================}

function Fact(N: integer): integer;
{Get factorial of N}
var I: integer;
begin
Result:=1;
for I:=1 to N do Result:=Result * I;
end;


procedure SwapIntegers(var A1,A2: integer);
{Swap integer arguments}
var T: integer;
begin
T:=A1; A1:=A2; A2:=T;
end;


procedure TJTPermutator.Reset;
var I: integer;
begin
{ Preset items 0..n-1 or 1..n depending on base}
for I:=0 to High(Indices) do Indices[I]:=I + FBase;
{ initially all directions are set to RIGHT TO LEFT }
for I:=0 to High(Indices) do Dir[I]:=drRightToLeft;
NextCount:=0;
end;


procedure TJTPermutator.SetPermutations(const Value: integer);
begin
if FPermutations<>Value then
	begin
	FPermutations := Value;
	SetLength(Indices,Value);
	SetLength(Dir,Value);
	Reset;
	end;
end;



constructor TJTPermutator.Create(Size: integer);
begin
ZeroBased:=True;
Permutations:=Size;
Reset;
end;



procedure TJTPermutator.SetZeroBased(const Value: boolean);
begin
if FZeroBased<>Value then
	begin
	FZeroBased := Value;
	if Value then FBase:=0
	else FBase:=1;
	Reset;
	end;
end;


function TJTPermutator.Next: boolean;
{Step to next permutation}
{Returns true when sequence completed}
var Mobile,Pos,I: integer;
var S: string;

	function FindLargestMoble(Mobile: integer): integer;
	{Find position of largest mobile integer in A}
	var I: integer;
	begin
	for I:=0 to  High(Indices) do
	 if Indices[I] = Mobile then
		begin
		Result:=I + 1;
		exit;
		end;
	Result:=-1;
	end;


	function GetMobile: integer;
	{ find the largest mobile integer.}
	var LastMobile, Mobile: integer;
	var I: integer;
	begin
	LastMobile:= 0; Mobile:= 0;
	for I:=0 to High(Indices) do
		begin
		{ direction 0 represents RIGHT TO LEFT.}
		if (Dir[Indices[I] - 1] = drRightToLeft) and (I<>0) then
			begin
			if (Indices[I] > Indices[I - 1]) and (Indices[I] > LastMobile) then
				begin
				Mobile:=Indices[I];
				LastMobile:=Mobile;
				end;
			end;

	        { direction 1 represents LEFT TO RIGHT.}
	        if (dir[Indices[I] - 1] = drLeftToRight) and (i<>(Length(Indices) - 1)) then
			begin
			if (Indices[I] > Indices[I + 1]) and (Indices[I] > LastMobile) then
				begin
				Mobile:=Indices[I];
				LastMobile:=Mobile;
				end;
			end;
		end;

	if (Mobile = 0) and (LastMobile = 0) then Result:=0
	else Result:=Mobile;
	end;



begin
Inc(NextCount);
Result:=NextCount>=Fact(Length(Indices));
if Result then
	begin
	Reset;
	exit;
	end;
Mobile:=GetMobile;
Pos:=FindLargestMoble(Mobile);

{ Swap elements according to the direction in Dir}
if (Dir[Indices[pos - 1] - 1] = drRightToLeft) then SwapIntegers(Indices[Pos - 1], Indices[Pos - 2])
else if (dir[Indices[pos - 1] - 1] = drLeftToRight) then SwapIntegers(Indices[Pos], Indices[Pos - 1]);

{ changing the directions for elements}
{ greater than largest Mobile integer.}
for I:=0 to High(Indices) do
 if Indices[I] > Mobile then
	begin
	if Dir[Indices[I] - 1] = drLeftToRight then Dir[Indices[I] - 1]:=drRightToLeft
	else if (Dir[Indices[i] - 1] = drRightToLeft) then Dir[Indices[I] - 1]:=drLeftToRight;
        end;
end;


{==============================================================================}




function GetPermutationStr(PM: TJTPermutator): string;
var I: integer;
begin
Result:=Format('%2d - [',[PM.NextCount+1]);
for I:=0 to High(PM.Indices) do Result:=Result+IntToStr(PM.Indices[I]);
Result:=Result+'] Sign: ';
if (PM.NextCount and 1)=0 then Result:=Result+'+1'
else Result:=Result+'-1';
end;



procedure SwapPermutations(Memo: TMemo);
var PM: TJTPermutator;
begin
PM:=TJTPermutator.Create(3);
try
repeat Memo.Lines.Add(GetPermutationStr(PM))
until PM.Next;
Memo.Lines.Add('');

PM.Permutations:=4;
repeat Memo.Lines.Add(GetPermutationStr(PM))
until PM.Next;
finally PM.Free; end;
end;


  

You may also check:How to resolve the algorithm Count in octal step by step in the Haskell programming language
You may also check:How to resolve the algorithm Super-d numbers step by step in the Wren programming language
You may also check:How to resolve the algorithm Averages/Mean angle step by step in the Stata programming language
You may also check:How to resolve the algorithm Generic swap step by step in the F# programming language
You may also check:How to resolve the algorithm Mutex step by step in the Shale programming language