Script used to test.
#include <Array.au3>
HotKeySet("|", "Stop")
Func Stop
()
$dif = TimerDiff($begin)
FileWriteLine($file, $a & " element test: Ran for " & $dif & " ms when user killed script.")
Exit
EndFunc ;==>Stop
$file = FileOpen("TestResults4.txt", 2)
For $a = 3 To 19
Switch $a
Case 3
Dim $aArray[3] = ["a", "b", "c"]
Case 4
Dim $aArray[4] = ["a", "a", "b", "c"]
Case 5
Dim $aArray[5] = ["a", "a", "b", "b", "c"]
Case 6
Dim $aArray[6] = ["a", "a", "b", "b", "c", "c"]
Case 7
Dim $aArray[7] = ["a", "a", "a", "b", "b", "c", "c"]
Case 8
Dim $aArray[8] = ["a", "a", "a", "b", "b", "b", "c", "c"]
Case 9
Dim $aArray[9] = ["a", "a", "a", "b", "b", "b", "c", "c", "c"]
Case 10
Dim $aArray[10] = ["a", "a", "a", "a", "b", "b", "b", "c", "c", "c"]
Case 11
Dim $aArray[11] = ["a", "a", "a", "a", "b", "b", "b", "b", "c", "c", "c"]
Case 12
Dim $aArray[12] = ["a", "a", "a", "a", "b", "b", "b", "b", "c", "c", "c", "c"]
Case 13
Dim $aArray[13] = ["a", "a", "a", "a", "a", "b", "b", "b", "b", "c", "c", "c", "c"]
Case 14
Dim $aArray[14] = ["a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "c", "c", "c", "c"]
Case 15
Dim $aArray[15] = ["a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "c", "c", "c", "c", "c"]
Case 16
Dim $aArray[16] = ["a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "c", "c", "c", "c", "c"]
Case 17
Dim $aArray[17] = ["a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "c", "c", "c", "c", "c"]
Case 18
Dim $aArray[18] = ["a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "c", "c", "c", "c", "c", "c"]
Case 19
Dim $aArray[19] = ["a", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "c", "c", "c", "c", "c", "c"]
EndSwitch
$begin = TimerInit()
;test 1
$aRet = _PermuteUnique
($aArray)
;test 2
;change _ArrayUnique to _ArrayUniqueAlternate in the _Recurse function
;test 3
;~ $aRet = _ArrayPermute($aArray,"")
;~ _ArrayDelete($aArray,0)
;~ $aRet = _ArrayUnique($aArray)
;~ _ArrayDelete($aArray,0)
;test 4
;~ $aRet = _ArrayPermute($aArray, "")
;~ _ArrayDelete($aArray, 0)
;~ $aRet = _ArrayUniqueAltered($aArray)
;~ _ArrayDelete($aArray, 0)
$dif = TimerDiff($begin)
;MsgBox(0,"Time","Time for _PermuteUnique to compute: "&$dif&" ms.")
FileWriteLine($file, $a & " element test: " & $dif & " ms.")
;_ArrayDisplay($aRet, "Finished")
Next
Func _PermuteUnique
($aArray)
Local $iBound = UBound($aArray), $sUniqStr = "", $sDupeStr = ""
For $i = 0 To $iBound - 1
If StringInStr($sUniqStr, $aArray[$i]) Then
$sDupeStr &= $aArray[$i]
Else
$sUniqStr &= $aArray[$i]
EndIf
Next
$aDupe = StringSplit($sDupeStr, "", 2)
$aUnique = StringSplit($sUniqStr, "", 2)
$aUnique = _ArrayPermute($aUnique)
_ArrayDelete($aUnique, 0)
Local $iLen = StringLen($aUnique[0]), $iStart = 0
_Recurse
($aUnique, $aDupe, $iStart, $iLen)
Return $aUnique
EndFunc ;==>_PermuteUnique
Func _Recurse
(ByRef $aSeed, $aDupe, ByRef $iIndex, ByRef $iLen)
If $iIndex = UBound($aDupe) Then Return
Local $aTempArray = $aSeed, $iBound = UBound($aSeed), $iCount = 0
ReDim $aSeed[$iBound * $iLen]
For $i = 0 To $iBound - 1
For $j = 0 To $iLen
$sTemp = $aTempArray[$i]
$aSeed[$iCount] = StringLeft($sTemp, $j) & $aDupe[$iIndex] & StringRight($sTemp, $iLen - $j)
$iCount += 1
While StringMid($aTempArray[$i], $j + 1, 1) = $aDupe[$iIndex]
$j += 1
WEnd
Next
Next
ReDim $aSeed[$iCount]
$aSeed = _ArrayUniqueAltered
($aSeed) ; Optimization improvements can be made here.
_ArrayDelete($aSeed, 0)
$iIndex += 1
$iLen += 1
_Recurse
($aSeed, $aDupe, $iIndex, $iLen)
EndFunc ;==>_Recurse
Func _ArrayUniqueAltered
($aArray, $iDimension = 1, $iBase = 0, $iCase = 0, $vDelim = "|")
Local $iUboundDim
;$aArray used to be ByRef, but litlmike altered it to allow for the choosing of 1 Array Dimension, without altering the original array
If $vDelim = "|" Then $vDelim = Chr(01) ; by SmOke_N, modified by litlmike
If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;Check to see if it is valid array
;Checks that the given Dimension is Valid
If Not $iDimension > 0 Then
Return SetError(3, 0, 0) ;Check to see if it is valid array dimension, Should be greater than 0
Else
;If Dimension Exists, then get the number of "Rows"
$iUboundDim = UBound($aArray, 1) ;Get Number of "Rows"
If @error Then Return SetError(3, 0, 0) ;2 = Array dimension is invalid.
;If $iDimension Exists, And the number of "Rows" is Valid:
Local $sHold ;String that holds the Unique array info
For $iCC = $iBase To UBound($aArray) - 1 ;Loop Through array
;If Not the case that the element is already in $sHold, then add it
If Not StringInStr($vDelim & $sHold, $vDelim & $aArray[$iCC] & $vDelim, $iCase) Then _
$sHold &= $aArray[$iCC] & $vDelim
Next
If $sHold Then
Dim $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 1) ;Split the string into an array
Return $aArrayTmp ;SmOke_N's version used to Return SetError(0, 0, 0)
EndIf
Return SetError(2, 0, 0) ;If the script gets this far, it has failed
EndIf
EndFunc ;==>_ArrayUniqueAltered
#cs
; This code is much slower (and more limited).
Dim $aPermute = _ArrayPermute($aArray)
_ArrayDelete($aPermute, 0)
$aPermute = _ArrayUnique($aPermute)
_ArrayDisplay($aPermute)
#ce
3 element test: 1.52304918106383 ms.
4 element test: 2.13164707554864 ms.
5 element test: 4.77711393276418 ms.
6 element test: 26.5786837163017 ms.
7 element test: 111.516737873085 ms.
8 element test: 814.202927070161 ms.
9 element test: 12205.1820814222 ms.
10 element test: 99809.0752904997 ms.
3 element test: 7.90294353118991 ms.
4 element test: 7.7327701666305 ms.
5 element test: 15.7939228875637 ms.
6 element test: 20.9868162126166 ms.
7 element test: 65.3061003075219 ms.
8 element test: 475.403175482046 ms.
9 element test: 3968.00764315483 ms.
10 element test: 25263.6427919401 ms.
11 element test: 202556.476670233 ms.
3 element test: 0.618706462450149 ms.
4 element test: 1.46774012525346 ms.
5 element test: 6.01344192623963 ms.
6 element test: 48.872326018152 ms.
7 element test: 286.205643139866 ms.
8 element test: 2262.94341147334 ms.
9 element test: 21868.2685803859 ms.
10 element test: 218767.773657117 ms.
3 element test: 0.757360698546192 ms.
4 element test: 2.54954021354443 ms.
5 element test: 6.08516711685086 ms.
6 element test: 37.1562600543214 ms.
7 element test: 266.872266159867 ms.
8 element test: 2279.98824907033 ms.
9 element test: 21707.7747308248 ms.
10 element test: 231333.086667315 ms.
Also, using test 2 array limit exceeds between 2000000 and 20000000. lol