# Logic Problem

hi ... if i've got a set of numbers say "123", how the shortest formula to
resulting the permutation of them to be : "123","132","213","231","312","321"? the result could be flexible depends on the length of numbers, right?

LVL 1
###### Who is Participating?

Commented:
Hi,
the working sample is bellow:

type
TForm1 = class(TForm)
LB: TListBox;
SpeedButton1: TSpeedButton;
procedure SpeedButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{\$R *.DFM}

function GenVariant(aBase,aWork : string) : string;
var I : integer;
begin
if aWork = '' then Form1.LB.Items.Add(aBase) else
for I:=1 to length(aWork) do
begin
result:=aWork;
delete(result,I,1);
GenVariant(aBase+aWork[I],result);
end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
GenVariant('','123');
end;

-----
Igor.
0

Commented:
Hi!

Do you want just one random combination or all of them?
0

Commented:
Hey Igor, nice code :-)
0

Commented:
Nice code Igor, but how does it really work?
0

Commented:
Just a tip:

if n is the number of characters in the input string, then n! is the number of possible combinations.

--johan
0

Author Commented:
that's a good logic, is there anyone could give other alternative? I will give my point in few next days ok ...
thanks to igor.
0

Commented:
Hi all,
I will try to explain my logic. It's very easy;)

To make all combination from the string you need to iterate through all characters in string.
.....
for I:=1 to length(aWork) do
.....
then you need to extract (delete) current character and iterate through remain of the string.
.....
result:=aWork;     // I use "result" as undeclared variable
delete(result,I,1); // result keep remain of the string
GenVariant(aBase+aWork[I],result); // recursive call to iterate with remain of the string
// first parameter keep characters extracted in previous iterations
.....

That's all. It more easy to understand under debugger watching on aBase and aWork parameters.

-----
Igor

PS: if you need not recursive logic then let me know.
0

Commented:
Well....I can't exactly say I understood more of it when you explained but I guess I'll understand it when I debug it in Delphi. Great code though! Good work, Igor!

--johan
0

Commented:
Hi all,
there is another one combinator (not recursive and standalone):

type

TStrCombintor = class(TObject)
fCNT : array of integer;
fIDX : integer;
procedure   Init(const V : string);
procedure   RollData(var V : string; Index : integer);
function    NextCombination(var V : string) : boolean;
end;

......

procedure TStrCombintor.Init(const V : string);
begin
SetLength(fCNT,length(V));
fIDX:=0;
end;

procedure TStrCombintor.RollData(var V : string; Index : integer);
var I  : integer;
C  : char;
begin
C:=V[1];
for I:=1 to Index+1 do V[I]:=V[I+1];
V[Index+1]:=C;
end;

function TStrCombintor.NextCombination(var V : string) : boolean;
begin
while fCNT[fIDX]>=fIDX+1 do
begin
RollData(V,fIDX+1);
fCNT[fIDX]:=0;
inc(fIDX);
end;
if fIDX < length(V)-1 then
begin
RollData(V,fIDX+1);
inc(fCNT[fIDX]);
fIDX:=0;
result:=true;
end else result:=false;
end;
---------------

and example how to use it:

procedure TForm1.SpeedButton1Click(Sender: TObject);
var SC : TStrCombintor;
S  : string;
begin
S  := '1234';
SC := TStrCombintor.Create;
SC.Init(S);
repeat
until not SC.NextCombination(S);
SC.Free;
end;

-----
Igor
0

Commented:
Hi,

and another one (not recursive):
-----

procedure MutateStr(S : string);
var C : array of integer;
I : integer;
begin
SetLength(C,Length(S)-1);
I:=0;
repeat
insert(S[1],S,I+3);
delete(S,1,1);
inc(C[I]);
if C[I]=I+2 then
begin
C[I]:=0;
inc(I);
end else
begin
I:=0;
end;
until I = Length(S)-1;
end;

-----
It doesn't show initial combination, only all another. Do not pass string with length < 2;)
-----
Igor.
0

Commented:
hi igor, i tried your code above with Delphi 3 and found error at this line:

var C : array of integer;

i suppose you didn't put the index of array?

0

Commented:
hi wuyinzhi,

this code for D5 you need to change

------OLD----- (D5)
var C : array of integer;
I : integer;
begin
SetLength(C,Length(S)-1);

----NEW---- (D3)
var C : array [0..255]  of integer;
I : integer;
begin
FillChar(C,SizeOf(C),#0);

------------

enjoy;)
-----
Igor
0

Commented:
Isn't it

counter = length of data
for iLoop = 1 to counter
0

Author Commented:
hi JohnnyBoy, I don't think your "answer" is an answer for the question, please refer to ITugay's program, he's got best solution so far.

0

Commented:
Why don't we end this thread? Igor has come up with many different variants of the code, propose an answer and end the thread, Igor!

--j exposing his thoughts...
0

Commented:
I wouldn't like to propose an answer. May be another experts have interest solutions. And it's decigion of questioner to accept comment as answer.
;-)

Igor
0

Commented:
Ok! I was just, as I said, exposing my current thought! ;o)

johan
0

Author Commented:
i already accepted igor's comment as right answer and gave my points. how could I do to lock this thread?
0

Commented:
No you haven't!
0

Commented:
hi powerfool,
If you like my answers then just click on "accept comment as answer" ;)
Igor.
0

Author Commented:
0

Author Commented:
Ok. I do it now.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.