Recursive approach based on Exeter algorithm, outputs strings but that could be changed input a set and choose a range.
Code: Select all
;idle permutation based on University of Exeter algorithm, should handle any default type, though only retuns strings at the moment
;CreatePermutations(*set,range,size of type, print out list)
;eg
;set.s = "easter"
;CreatePermutations(@set,6,#TCHAR,#True)
;Or
;CreatePermutationsRange(5,8,#TFLOAT,#True,0.50)
Global ct.i
Global NewList lout.s()
Enumeration
#TBYTE
#TCHAR
#TWORD
#TLONG
#TFLOAT
#TDOUBLE
#TQUAD
EndEnumeration
Procedure Permute(*V,start,n,sizeofV)
If start = n-1
If *v
sout.s
For i = 0 To n -1
Select sizeofV
Case #TBYTE
tv = PeekB(*V+i)
sout + Str(tv) + " "
Case #TCHAR
tw.c = PeekC(*V+(i* SizeOf(Character)))
sout + Chr(tw)
Case #TWORD
tww.w = PeekW(*V+(i*SizeOf(WORD)))
sout + Str(tww) + " "
Case #TLONG
ti.i = PeekI(*V+(i*SizeOf(LONG)))
sout + Str(ti) + " "
Case #TFLOAT
tf.f = PeekF(*V+(i*SizeOf(Float)))
sout + StrF(tf,7) + " "
Case #TDOUBLE
td.d = PeekD(*V+(i*SizeOf(DOUBLE)))
sout + StrD(td,15) + " "
Case #TQUAD
tq.q = PeekQ(*V+(i*SizeOf(QUAD)))
sout + Str(tq) + " "
EndSelect
Next
AddElement(lout())
lout()= sout
ct+1
EndIf
Else
For i = start To n -1
Select sizeofV
Case #TBYTE
tmpb.b = PeekB(*V+i)
PokeB(*v+i,PeekB(*v+start));
PokeB(*v+start,tmpb)
permute(*v, start+1, n,sizeofV);
PokeB(*v+start,PeekB(*v+i));
PokeB(*v+i,tmpb);
Case #TCHAR
sz = SizeOf(Character)
tmpc.c = PeekC(*V+(i*sz))
PokeC(*v+(i*sz),PeekC(*v+(start*sz)));
PokeC(*v+(start*sz),tmpc)
permute(*v,start+1,n,sizeofV);
PokeC(*v+(start*sz),PeekC(*v+(i*sz)))
PokeC(*v+(i*sz),tmpc);
Case #TWORD
sz = SizeOf(WORD)
tmpw.w = PeekW(*V+(i*sz))
PokeW(*v+(i*sz),PeekW(*v+(start*sz)));
PokeW(*v+(start*sz),tmpw)
permute(*v,start+1,n,sizeofV);
PokeW(*v+(start*sz),PeekW(*v+(i*sz)))
PokeW(*v+(i*sz),tmpw);
Case #TLONG
sz = SizeOf(LONG)
tmpl.i = PeekI(*V+(i*sz))
PokeI(*v+(i*sz),PeekI(*v+(start*sz)));
PokeI(*v+(start*sz),tmpl)
permute(*v, start+1, n,sizeofV);
PokeI(*v+(start*sz),PeekI(*v+(i*sz)))
PokeI(*v+(i*sz),tmpl);
Case #TFLOAT
sz =SizeOf(FLOAT)
tmpf.f = PeekF(*V+(i*sz))
PokeF(*v+(i*sz),PeekF(*v+(start*sz)));
PokeF(*v+(start*sz),tmpf)
permute(*v, start+1, n,sizeofV);
PokeF(*v+(start*sz),PeekF(*v+(i*sz)))
PokeF(*v+(i*sz),tmpf);
Case #TDOUBLE
sz = SizeOf(DOUBLE)
tmpd.d = PeekD(*V+(i*sz))
PokeD(*v+(i*sz),PeekD(*v+(start*sz)));
PokeD(*v+(start*sz),tmpd)
permute(*v, start+1, n,sizeofV);
PokeD(*v+(start*sz),PeekD(*v+(i*sz)))
PokeD(*v+(i*sz),tmpd);
Case #TQUAD
sz = SizeOf(QUAD)
tmpq.q = PeekQ(*V+(i*sz))
PokeQ(*v+(i*sz),PeekQ(*v+(start*sz)));
PokeQ(*v+(start*sz),tmpq)
permute(*v, start+1, n,sizeofV);
PokeQ(*v+(start*sz),PeekQ(*v+(i*sz)))
PokeQ(*v+(i*sz),tmpq);
EndSelect
Next
EndIf
EndProcedure
Procedure CreatePermutations(*set,range,sizet,print)
ct = 0
permute(*set,0,range,sizet)
If print
ForEach lout()
PrintN(lout())
Next
EndIf
ClearList(lout())
EndProcedure
Procedure CreatePermutationsRange(Rstart.q,REnd.q,type,print,steps.f=1.0)
len= (Rend-Rstart)+1
Select type
Case #TBYTE
*tset = AllocateMemory(Rend-Rstart)
For a = 0 To len-1
PokeB(*tset+a,a+rstart)
Next
Case #TWORD
*tset = AllocateMemory((Rend-Rstart)*SizeOf(WORD))
sz = SizeOf(word)
For a = 0 To len -1
PokeW(*tset+(a*sz),a+rstart)
Next
Case #TLONG
*tset = AllocateMemory((Rend-Rstart)*SizeOf(LONG))
sz = SizeOf(long)
For a = 0 To len-1
PokeI(*tset+(a*sz),a+rstart)
Next
Case #TFLOAT
ctf.f = Rstart
sz = SizeOf(float)
len = (len * (1/steps)) -1
*tset = AllocateMemory(len*sz)
For a = 0 To len - 1
PokeF(*tset+(a*sz),ctf)
ctf+steps
Next
Case #TDOUBLE
ctd.d = Rstart
sz = SizeOf(Double)
len = (len * (1/steps)) -1
*tset = AllocateMemory(len*sz)
For a = 0 To len - 1
PokeD(*tset+(a*sz),ctd)
ctd+steps
Next
Case #TQUAD
*tset = AllocateMemory((Rend-Rstart)*SizeOf(quad))
sz = SizeOf(Quad)
For a = 0 To len-1
PokeQ(*tset+(a*sz),a+rstart)
Next
EndSelect
CreatePermutations(*tset,len,type,print)
FreeMemory(*tset)
EndProcedure
;#########################test code below#################################
OpenConsole()
;timing run
na = 100
set.s = "easter"
st = GetTickCount_()
For a = 0 To na
CreatePermutations(@Set,6,#TCHAR,#False)
Next
et.s = StrF(((GetTickCount_() - st)/na),3) + " milliseconds "
PrintN(Str(ct) + " Permutations Avgerage Time " + et + " =========================")
PrintN("Hit Enter to continue")
Input()
;###########
CreatePermutationsRange(5,7,#TFLOAT,#True,0.50)
PrintN(Str(ct) + " permutations of float range 5 to 7 =======================================")
PrintN("Hit Enter to continue")
Input()
CreatePermutations(@set,6,#TCHAR,#True)
PrintN(Str(ct) + " Chr Permutations =======================================")
PrintN("Hit Enter to continue")
Input()
;array of vals
Dim bSet.b(5)
bSet(0) = 1
bSet(1) = 2
bSet(2) = 3
bSet(3) = 4
bSet(4) = 5
CreatePermutations(@bSet(0),5,#TBYTE,#True)
PrintN(Str(ct) + " Byte Permutations =======================================")
PrintN("Hit Enter to continue")
Input()
;array of vals
Dim wSet.w(5)
wSet(0) = 1111
wSet(1) = 2222
wSet(2) = 3333
wSet(3) = 4444
wSet(4) = 5555
CreatePermutations(@wSet(0),5,#TWORD,#True)
PrintN(Str(ct) + " Word Permutations =======================================")
PrintN("Hit Enter to continue")
Input()
Dim iSet.i(6)
iSet(0) = 6666
iSet(1) = 7777
iSet(2) = 8888
iSet(3) = 9999
iSet(4) = 1000
iSet(5) = 2000
CreatePermutations(@iSet(0),5,#TLONG,#True)
PrintN(Str(ct) + " Long Permutations =======================================")
PrintN("Hit Enter to continue")
Input()
Dim fSet.f(6)
fset(0) = 1.1234
fset(1) = 2.1234
fset(2) = 3.1234
fset(3) = 4.1234
fset(4) = 5.1234
fset(5) = 6.1234
CreatePermutations(@fSet(0),5,#TFLOAT,#True)
PrintN(Str(ct) + " Float Permutations =======================================")
PrintN("Hit Enter to continue")
Input()
Dim dSet.d(6)
dset(0) = 1.1234
dset(1) = 2.1234
dset(2) = 3.1234
dset(3) = 4.1234
dset(4) = 5.1234
dset(5) = 6.1234
CreatePermutations(@dSet(0),5,#TDOUBLE,#True)
PrintN(Str(ct) + " Double Permutations =======================================")
PrintN("Hit Enter to continue")
Input()
Dim qSet.q(6)
qset(0) = 112341111
qset(1) = 212341111
qset(2) = 312311214
qset(3) = 412311212
qset(4) = 512341212
qset(5) = 612312214
CreatePermutations(@qSet(0),5,#TQUAD,#True)
PrintN(Str(ct) + " Quad Permutations =======================================")
PrintN("Hit Enter to continue")
Input()
CloseConsole()