Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

All Combinations 1

Status
Not open for further replies.

skoko

Programmer
Feb 11, 2002
188
US
What I need is all possible combinations from let say ABCD.

ABCD
ABDC
ADBC
BACD
BADC
BCAD
BCDA.....

Algorithm will be higly appreciated :)
 
FOR lnLetter1 = 65 TO 68 &&chars A- D
FOR lnLetter2 = 65 TO 68 &&chars A- D
FOR lnLetter3 = 65 TO 68 &&chars A- D
FOR lnLetter4 = 65 TO 68 &&chars A- D
lcString=CHR(lnLetter1)+CHR(lnLetter2)+CHR(lnLetter3)+CHR(lnLetter4)
?lcString
ENDFOR
ENDFOR
ENDFOR
ENDFOR

Brian
 
Thanx Brian, but each letter can show only once.
 
Is this a homework project?

It has the appearance of one.
It is hard to imagine a real-world use for this.

If not, I apologize for any possible implications.
If so, it is a Red Flag posting.

Good Luck,
JRB-Bldr
 
JRB-Bldr, this is not my first post on this forum, if you run search, you will definetly find that I'm not in school anymore.

I tried to make this question as short as possible, but with your help now I need to explain WHY I need that.

As I state, if you read previous posts of mine (some more than two years old), you will find that I'm working in college building Student Data Base system.

Next project is Scheduler. So, after enrollment, application will schedule student classes in already scheduled classes. Some classes need to be taken first, some have prerequisits and so on.

I figure, that after scheduling classes that need to be taken first just run algorithm to calculate all possible combinations of rest of the classes and compare them with a classrom availability.

So, JRB-Bldr, now, when I spend 10 minutes typing, do you have answer on my question in first place?
 
This is a quick and dirty way:

FOR lnLetter1 = 65 TO 68
FOR lnLetter2 = 65 TO 68
IF lnLetter2 # lnLetter1
FOR lnLetter3 = 65 TO 68
IF lnLetter3 # lnLetter1 AND lnLetter3 # lnLetter2
FOR lnLetter4 = 65 TO 68
IF lnLetter4 # lnLetter1 AND lnLetter4 # lnLetter2 AND lnLetter4 # lnLetter3
lcString=CHR(lnLetter1)+CHR(lnLetter2)+CHR(lnLetter3)+CHR(lnLetter4)
?lcString
ENDIF
ENDFOR
ENDIF
ENDFOR
ENDIF
ENDFOR
ENDFOR
 
Hey, if you're trying to calculate combinations of classes, I wouldn't hard-code. Why not use a table or cursor of classes and create all possible combinations using SCAN ... ENDSCAN and reccount(). Easier to update available classes later.

Brian
 
Thank You Baltman, but number of classes is n.

Anyhow, I figure it out, example below will print on screen all combinations:

Code:
DIMENSION xx(4)
FOR x=1 TO 4
	xx(x)=CHR(x+64)
ENDFOR

FOR a=1 TO 4
		FOR c=1 TO 4
			?? xx(c)
		ENDFOR 
		?
	FOR b=1 TO 3
		cc=xx(b)
		xx(b)=xx(b+1)
		xx(b+1)=cc
		FOR c=1 TO 4
			?? xx(c)
		ENDFOR 
		?
		cc=xx(b)
		xx(b)=xx(b+1)
		xx(b+1)=cc
	ENDFOR 
	?
	cc=xx(1)
	FOR x=1 TO 3
		xx(x)=xx(x+1)
	ENDFOR 
	xx(4)=cc
ENDFOR
 
Baltman, using mine previous code, entire procedure should look something like this:

Code:
USE classes_to_take IN 1 ORDER class_code
USE class_rooms IN 2 ORDER class_code
CREATE CURSOR temp (cl1 c(5), cl2 c(5), cl3 c(5), cl4(c5), cl5 c(5), cl6 c(5), cl7(c5), cl8 c(5), cl9 c(5), cl10 c(5))

DIMENSION xx(10)

SELECT 1
xx=1
SCAN FOR EOF()=.f.
	xx(x)=classes_to_take.class_code
	xx=xx+1
ENDFOR

SELECT temp 
FOR a=1 TO 10
	INSERT INTO temp VALUES (xx(1), xx(2), xx(3), xx(4), xx(5), xx(6), xx(7), xx(8), xx(9), xx(10))		
	FOR b=1 TO 3
		cc=xx(b)
		xx(b)=xx(b+1)
		xx(b+1)=cc
		FOR c=1 TO 4
			INSERT INTO temp VALUES (xx(1), xx(2), xx(3), xx(4), xx(5), xx(6), xx(7), xx(8), xx(9), xx(10))		
		ENDFOR 
		cc=xx(b)
		xx(b)=xx(b+1)
		xx(b+1)=cc
	ENDFOR 
	cc=xx(1)
	FOR x=1 TO 3
		xx(x)=xx(x+1)
	ENDFOR 
	xx(4)=cc
ENDFOR 

_done=.t.
SCAN FOR EOF()=.f.
	SELECT class_rooms
	FOR x=1 TO 10
		a='seek cl'+ALLTRIM(STR(x,2,0))
		&a
		IF !FOUND()
			_done=.f.
			EXIT
		ENDIF 
	ENDFOR 	
	IF _done=.t.
		EXIT
	ELSE
		_done=.t.
	ENDIF 
ENDSCAN

I'm not sure what you meant by SCAN ... ENDSCAN and reccount()
JRB-Bldr, now when you know that this is not homework, maybe you have something to add :)
 
Oops, typed wrong:

Code:
SELECT temp 
FOR a=1 TO 10
    INSERT INTO temp VALUES (xx(1), xx(2), xx(3), xx(4), xx(5), xx(6), xx(7), xx(8), xx(9), xx(10))        
    FOR b=1 TO 9
        cc=xx(b)
        xx(b)=xx(b+1)
        xx(b+1)=cc
        FOR c=1 TO 9
            INSERT INTO temp VALUES (cc(1), cc(2), cc(3), cc(4), cc(5), cc(6), cc(7), cc(8), cc(9), cc(10))        
        ENDFOR 
        cc=xx(b)
        xx(b)=xx(b+1)
        xx(b+1)=cc
    ENDFOR 
    cc=xx(1)
    FOR x=1 TO 9
        xx(x)=xx(x+1)
    ENDFOR 
    xx(10)=cc
ENDFOR
 
What is being spoken of here is Permutations not Combinations. Using nested FOR loop structures is ok, except that it really isn't very scalable. Here is some code that I wrote that could be used (I didn't use recursive function calls since that is also limiting - you can run into a nesting exception, though an argument could be made that my use of array's is limiting in it's own right - cursors could be used instead, but in the end there will always some sort of limitation, so I am just limiting it within reason I guess). Cut-N-Paste the examples below into a prg and run from within VFP:

PERMUTATIONS
Code:
DIMENSION aryGroup(4)
aryGroup(1) = [a]
aryGroup(2) = [b]
aryGroup(3) = [c]
aryGroup(4) = [d]
CLEAR
?[Set of 4 Size 1 (4_P_1)]
?REPLICATE([-], 34)
GetPermutations(1,@aryGroup)
?
?
?[Set of 4 Size 2 (4_P_2)]
?REPLICATE([-], 34)
GetPermutations(2,@aryGroup)
?
?
?[Set of 4 Size 4 (4_P_4)]
?REPLICATE([-], 34)
GetPermutations(4,@aryGroup)

PROCEDURE GetPermutations(tcSize, tcSet)
	LOCAL lnMembers, lnCounter, lnTemp, lnTemp2
	lnMembers = ALEN(tcSet)
	DIMENSION aryIndice(lnMembers)
	aryIndice = -1
	DO WHILE .T.
		IF(aryIndice(1) < 0)
			lnCounter = 1
			DO WHILE  lnCounter < lnMembers + 1
				aryIndice(lnCounter) = lnCounter - 1
				lnCounter = lnCounter + 1 && was above
			ENDDO
			lnBeginning = tcSize +1
			lnEnd = lnMembers
			DO WHILE lnBeginning < lnEnd
				lnTemp2 = aryIndice(lnBeginning)
				aryIndice(lnBeginning) = aryIndice(lnEnd)
				lnBeginning = lnBeginning + 1
				aryIndice(lnEnd) = lnTemp2
				lnEnd = lnEnd - 1
			ENDDO
			?LEFT(DisplayString(lnMembers, @tcSet, @aryIndice), tcSize)
			LOOP
		ELSE
			lnCounter = lnMembers - 1
			DO WHILE lnCounter >= 1 AND aryIndice(lnCounter) >= aryIndice(lnCounter + 1)
				lnCounter = lnCounter - 1
			ENDDO
			IF(lnCounter < 1)
				EXIT
			ELSE
				lnLeast = lnCounter + 1
				lnTemp = lnCounter + 2
				DO WHILE lnTemp < lnMembers + 1
					IF(aryIndice(lnTemp) < aryIndice(lnLeast) AND aryIndice(lnTemp) > aryIndice(lnCounter))
						lnLeast = lnTemp
					ENDIF
					lnTemp = lnTemp + 1 && was above
				ENDDO
				lnTemp2 = aryIndice(lnCounter)
				aryIndice(lnCounter) = aryIndice(lnLeast)
				aryIndice(lnLeast) = lnTemp2
				IF (tcSize > lnCounter)
					lnBeginning = lnCounter + 1
					lnEnd = lnMembers
					DO WHILE lnBeginning < lnEnd
						lnTemp2 = aryIndice(lnBeginning)
						aryIndice(lnBeginning) = aryIndice(lnEnd)
						lnBeginning = lnBeginning + 1
						aryIndice(lnEnd) = lnTemp2
						lnEnd = lnEnd - 1
					ENDDO
					lnBeginning = tcSize + 1
					lnEnd = lnMembers
					DO WHILE lnBeginning < lnEnd
						lnTemp2 = aryIndice(lnBeginning)
						aryIndice(lnBeginning) = aryIndice(lnEnd)
						lnBeginning = lnBeginning + 1
						aryIndice(lnEnd) = lnTemp2
						lnEnd = lnEnd - 1
					ENDDO
				ENDIF
				?LEFT(DisplayString(lnMembers, @tcSet, @aryIndice), tcSize)
				LOOP
			ENDIF
		ENDIF
	ENDDO
ENDPROC


FUNCTION DisplayString(tcMembers, tcSet, tcIndice)
	LOCAL lnCounter, lcString
	lcString = []
	FOR lnCounter = 1 TO tcMembers
		IF (tcIndice(lnCounter) + 1) != 0
			lcString = lcString + TRANSFORM(tcSet(tcIndice(lnCounter)+1))
		ENDIF
	ENDFOR
	RETURN ALLTRIM(lcString)
ENDFUNC

COMBINATIONS
Code:
DIMENSION aryGroup(4)
aryGroup(1) = [a]
aryGroup(2) = [b]
aryGroup(3) = [c]
aryGroup(4) = [d]
CLEAR
?[Set of 4 Choose 1 (4_C_1)]
?REPLICATE([-], 34)
GetCombinations(2,@aryGroup)
?
?
?[Set of 4 Choose 2 (4_C_2)]
?REPLICATE([-], 34)
GetCombinations(2,@aryGroup)
?
?
?[Set of 4 Choose 3 (4_C_3)]
?REPLICATE([-], 34)
GetCombinations(3,@aryGroup)
?
?
?[Set of 4 Choose 4 (4_C_4)]
?REPLICATE([-], 34)
GetCombinations(4,@aryGroup)

PROCEDURE GetCombinations(tcSize, tcSet)
	LOCAL lnMembers, lnCounter, lnTemp
	lnMembers = ALEN(tcSet)
	DIMENSION aryIndice(lnMembers)
	aryIndice = 0
	DO WHILE .T.
		IF aryIndice(1) < 1
			lnCounter = 1
			FOR lnCounter = 1 TO tcSize
				aryIndice(lnCounter) = lnCounter
			ENDFOR
			?DisplayString(lnMembers, @tcSet, @aryIndice)
			LOOP
		ELSE
			lnCounter = tcSize &&- 1
			DO WHILE lnCounter >= 1 AND aryIndice(lnCounter) >= (lnMembers - tcSize + lnCounter)
				lnCounter = lnCounter - 1
			ENDDO
			IF(lnCounter >= 1)
				aryIndice(lnCounter) = aryIndice(lnCounter) + 1
				lnTemp = lnCounter
				DO WHILE lnTemp < tcSize
					lnTemp = lnTemp + 1
					aryIndice(lnTemp) = aryIndice(lnTemp-1) + 1
				ENDDO
				?DisplayString(lnMembers, @tcSet, @aryIndice)
				LOOP
			ELSE
				EXIT
			ENDIF
		ENDIF
	ENDDO
ENDPROC

FUNCTION DisplayString(tcMembers, tcSet, tcIndice)
	LOCAL lnCounter, lcString
	lcString = []
	FOR lnCounter = 1 TO tcMembers
		IF tcIndice(lnCounter) != 0
			lcString = lcString + TRANSFORM(tcSet(tcIndice(lnCounter)))
		ENDIF
	ENDFOR
	RETURN ALLTRIM(lcString)
ENDFUNC

boyd.gif

craig1442@mchsi.com
&quot;Whom computers would destroy, they must first drive mad.&quot; - Anon​
 
Hi,
I am not 100% sure this is what you are looking for, mainly because I fail to follow your codings with all the "x" and "c" variables. I have however constructed a function which finds any combination of given letters, inclusive a ? wildcard in a table.
In this particular case it finds in a Dutch Dictionary all words with the given letters, a anagram function.
So input ADRP in cWoord TextBox will result in existing words: DARP and DRAP and input D?RP in cWoord would result into DARP DRAP DREP DORP ROPD e.s.o.
Is this something you are looking for? If so it could be modified into your needs easily
Koen
Code:
LOCAL lnI, lnI2, lnVar,lnN,lcWoord,lcNwrd,lcN,lnVrgt,lcNsolo
STORE 0 TO lnVar,lnVrgt
STORE " " TO lcWoord, lcNwrd, lcNsolo
RELEASE MyArray*
WITH ThisForm
   lnVar = LEN(ALLTRIM(LOWE(.cWoord.Value)))
   lcWoord = ALLTRIM(LOWE(.cWoord.Value))
   FOR lnI = 1 TO lnVar
     lcN = SUBS(lcWoord,lnI,1)
     DO CASE
        CASE lcN = "?"
             lcN = ""
             lnVrgt = lnVrgt+1
     ENDC
     lcNwrd = lcNwrd+lcN                               
   ENDFOR
   lcNwrd = ALLTRIM(lcNwrd)
   lnN = LEN(lcNwrd)+lnVrgt
   FOR lnI2 = 1 TO lnN
      IF OCCU(SUBS(lcNwrd,lnI2,1),lcNsolo)<1
         lcNsolo=lcNsolo+SUBS(lcNwrd,i,1)
      ENDI
   ENDFOR
ENDWITH   


SELECT woord FROM nederlands WHERE MyUDF(TRIM(compwoord),lcNwrd,lnVar,lcNsolo) ;
   AND DELETED()=.F. INTO ARRAY.myArray  


FUNCTION MyUDF
PARA tcField,tcPattern,tnLength,tcSolo
LOCAL lnI, lnI2 
DO CASE
	CASE "?" $ tcPattern
   		FOR lnI = 1 TO LEN(tcSolo)
   			DO CASE
   				CASE OCCU(SUBS(tcSolo,lnI,1),tcField) < OCCU(SUBS(tcSolo,lnI,1),tcPattern) 
   					RETU .F.
   			ENDC
   		ENDFOR
	CASE LEN(tcField) # tnLength
		RETU .F.
	OTHE
    	FOR lnI2 = 1 TO LEN(tcSolo) &&10
			DO CASE
				CASE OCCU(SUBS(tcSolo,lnI2,1),tcField) # OCCU(SUBS(tcSolo,lnI2,1),tcPattern) 
					RETU .F.
			ENDC
   ENDFOR
ENDC
 
Hi,

Brute Force! Not scalable or flexible, but it works.
Code:
cString = "ABCD"
tempString = cString
DO WHILE .T.
	? tempString
	DO ex3
	? tempString
	DO ex2
	? tempString
	DO ex3
	? tempString
	DO ex2
	? tempString
	DO ex3
	? tempString
	DO ex1
	IF tempString == cString
		EXIT
	ENDIF 
	? tempString
ENDDO 

PROCEDURE ex3
	tempString = LEFT(tempString,2) + ;
		RIGHT(tempString,1) + ;
		SUBSTR(tempString,3,1)
ENDPROC 

PROCEDURE ex2
	tempString = LEFT(tempString,1) + ;
		SUBSTR(tempString,3,1) + ;
		SUBSTR(tempString,2,1) + ;
		RIGHT(tempString,1)
ENDPROC 

PROCEDURE ex1
	tempString = SUBSTR(tempString,2,1) + ;
		SUBSTR(tempString,1,1) + ;
		SUBSTR(tempString,4,1) + ;
		SUBSTR(tempString,3,1)
ENDPROC
Regards,

Mike
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top