Jump to content

Algorithm to show all array's position


Go to solution Solved by jguinch,

Recommended Posts

I need help with this algorithm, the input is an array, like this:

$arr[3] = [2,4,3] (the array can contaim, any number, each number is any number), each number must be grater zero and positive

And show a sequence like this:

0 0 0  --> [0,0,0]

0 1 1

0 2 2

0 3 0

0 0 1

0 1 2

0 2 0

0 3 1

0 0 2

0 1 0

0 2 1

0 3 2

1 0 0  --> [1,0,0]

1 1 1

1 2 2

1 3 0

1 0 1

1 1 2

1 2 0

1 3 1

1 0 2

1 1 0

1 2 1

1 3 2  --> [1,3,2]

This algorithm I build to show the contents's array (any dimension: $aArray_a[1], $aArray_b[2][3], $aArray_c[2][3][4] or $aArray_d[1][2][3][4] or any kind of array... Not only $arr[1] or $arr[2][3]!

If you know another script/algorithm do make this (not necessary folow this idea), please, show-me, share with me this information, it is very important to me.

Thanks for any help.

 

Visit my repository

Link to comment
Share on other sites

ok, first, thanks for your replay!

I have dificulties to write in english, but, I will try clear...

The input array caled $aProperties, contain the caracteristcs of any array, like this...

If you array is:

$aColors[2] = ['blue', 'gray'], the $aProperties[1] = [2]

If you array is:

$aLanguage[2][3] = [ _

    ['green','Green'], ['red','Red'], ['yellow','Yellow'], _

    ['green', 'Verde'], ['red', 'Vermelho'], ['yellow', 'Amarelo'] _

]

The $aProperties[2] = [2,3]

Now, if you have an array like this...

Local $aNumbers[2][3][4] = [[[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]],[[13, 14, 15, 16],[17, 18, 19, 20],[21, 22, 23, 24]]]

The $aPropertis[3] = [2,3,4]

The $aProperties is a single array, order one ($arr[1]), and it contain all caracteristics from $aNumbers: lines [2], columns [3] and unfortunately i don't know how call this element [4]... sub-columns?

I try write one script, to build a combination beteween all numbers from array...

If your $array is $arr[3], the iteration for all elements is:

$arr[0]  --> 0

$arr[1]  --> 1

$arr[2]  --> 2

If your $array is $arr[2][3], the iteration for all elements is:

$arr[0][0]  --> 0 0

$arr[0][1]  --> 0 1

$arr[0][2]  --> 0 2

$arr[1][0]  --> 1 0

$arr[1][1]  --> 1 1

$arr[1][2]  --> 1 2

If your $array is $arr[2][3][4], the iteration for all elements is:

#1  $arr[0][0][0]  --> 0 0 0

#2  $arr[0][0][1]  --> 0 0 1

#3  $arr[0][0][2]  --> 0 0 2

#4  $arr[0][0][3]  --> 0 0 3

#5  $arr[0][1][0]  --> 0 1 0

#6  $arr[0][1][1]  --> 0 1 1

#7  $arr[0][1][2]  --> 0 1 2

#8  $arr[0][1][3]  --> 0 1 3

#9  $arr[0][2][0]  --> 0 2 0

#10 $arr[0][2][1]  --> 0 2 1

#11 $arr[0][2][2]  --> 0 2 2

#12 $arr[0][2][3]  --> 0 2 3

#13 $arr[1][0][0]  --> 1 0 0

#14 $arr[1][0][1]  --> 1 0 1

#15 $arr[1][0][2]  --> 1 0 2

#16 $arr[1][0][3]  --> 1 0 3

#17 $arr[1][1][0]  --> 1 1 0

#18 $arr[1][1][1]  --> 1 1 1

#19 $arr[1][1][2]  --> 1 1 2

#20 $arr[1][1][3]  --> 1 1 3

#21 $arr[1][2][0]  --> 1 2 0

#22 $arr[1][2][1]  --> 1 2 1

#23 $arr[1][2][2]  --> 1 2 2

#24 $arr[1][2][3]  --> 1 2 3

I find _ArrayPermute, but it work only array[1], does not works with $arra[nn][mm]... it's correct?

So... I find/search one algorithm do make this combinations typed in red...

Work with array one dimension ($arr[nn]) and array bi-dimensional ($arr[nn][mm]) is easy and I work very well...

I can't iterate/list the elements from array $arr[aa][bb][cc][dd]...[zz] 

I build a script to do this

For $ii = 0 To Ubound($arr, 1) -1

    For $jj = 0 To Ubound($arr, 2) -1

        For $kk = 0 To Ubound($arr, 3) -1 and so on... but it is not smart...

@jguinch, thank you for your question.

Edited by Detefon

Visit my repository

Link to comment
Share on other sites

  • Solution

Well, I'm not sure to really have understood...

I still give you a code to generate all combinations from a muliti-dimensional array :

#Include <Array.au3>


Local $arr[2][3][4]

$aCombinations = _Combinations($arr)
_ArrayDisplay($aCombinations)


Func _Combinations($aMyArray)
    Local $i = 0
    Local $iCount = 1

    While 1
        $i += 1
        $iLen = UBound($aMyArray, $i)
        If $iLen = 0 Then ExitLoop
        
        $iCount *= $iLen
    WEnd


    Local $aResult[$iCount]
    Local $iDims = $i - 1
    Local $iSwap = $iCount
    Local $iIndex, $iVal


    For $i = 0 To $iDims - 1
        $iSwap /= UBound($aMyArray, $i + 1)
        $iIndex = 0
        $iVal = 0
            
        For $j = 0 To $iCount - 1
            
            If $iIndex = $iSwap Then
                $iIndex = 0
                If $iVal = UBound($aMyArray, $i + 1) - 1 Then
                    $iVal = 0
                Else
                    $iVal += 1
                EndIf
            EndIf
            $aResult[$j] &= $iVal
            
        $iIndex += 1
        Next
    Next
    
    Return $aResult
EndFunc
Link to comment
Share on other sites

Detefon,

You appear to look for a magical in-depth iterator over elements of a multi-dimensionnal array giving you indices sequence for every entry. AutoIt doesn't offer that feature, so you must use nested For loops, which you said "and so on... but it is not smart..."

The problem isn't being smart or not, it's about using the language features for what they can offer.

BTW, _ArrayPermute and _ArrayCombinations are different unicorns entirely.

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I always have many doubts if my questions can be answered or are limitations AutoIt, and to make matters worse there are language barriers ... 
But I'm stubborn, has a lot that I do not ask here, and still keep polishing the code. 
@ jchd I agree with you ^ ^
 
@jguinch thank you very very very much!
I try build this code (my carnival was coding) for two or tree days, to obtain this array list, and then I was so tired I decided to ask around here and finally now I can iterate any type of array, for me, this was the discovery of the year!
 
#include <Array.au3>

Local $aTest0[3] = ['Hellow World!', 'Thank you very much!', 'Have a nice day']
Local $aTest1[2][3] = [['um', 'dois', 'três'],['quatro', 'cinco', 'seis']]
Local $aTest2[2][4][3] = [[[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12]],[[13, 14, 15],[16, 17, 18],[19, 20, 21],[22, 23, 24]]]

For $ii = 0 To 2
    ConsoleWrite('---' & @LF)
    $aCombinations = _Combinations(Eval('aTest' & $ii))
Next

Func _Combinations($arr)
    Local $i = 0
    Local $iCount = 1

    While 1
        $i += 1
        $iLen = UBound($arr, $i)
        If $iLen = 0 Then ExitLoop

        $iCount *= $iLen
    WEnd

    Local $aResult[$iCount]
    Local $iDims = $i - 1
    Local $iSwap = $iCount
    Local $iIndex, $iVal

    For $i = 0 To $iDims - 1
        $iSwap /= UBound($arr, $i + 1)
        $iIndex = 0
        $iVal = 0

        For $j = 0 To $iCount - 1
            If $iIndex = $iSwap Then
                $iIndex = 0
                If $iVal = UBound($arr, $i + 1) - 1 Then
                    $iVal = 0
                Else
                    $iVal += 1
                EndIf
            EndIf
            $aResult[$j] &= '[' & $iVal & ']'
            $iIndex += 1
        Next
    Next
    For $each In $aResult
        ConsoleWrite('$arr' & $each & '=' & Execute('$arr' & $each) & @LF)
    Next

    ;Return $aResult
EndFunc   ;==>_Combinations

Visit my repository

Link to comment
Share on other sites

Here is another approach.

Local $arr1[2]
ConsoleWrite("$arr1[2]" & @LF & _ArrayContains($arr1) & @LF)
ConsoleWrite("==================" & @LF)

Local $arr2[2][4]
ConsoleWrite("$arr2[2][4]" & @LF & _ArrayContains($arr2) & @LF)
ConsoleWrite("==================" & @LF)

Local $arr3[2][4][3]
ConsoleWrite("$arr3[2][4][3]" & @LF & _ArrayContains($arr3) & @LF)
ConsoleWrite("==================" & @LF)


Func _ArrayContains($arr)
    Local $sAns, $iVal, $iNumElem = 1, $aNumElem[UBound($arr, 0)]
    For $i = 1 To UBound($arr, 0)
        $iNumElem *= UBound($arr, $i)
        $aNumElem[$i - 1] = $iNumElem
    Next
    For $i = 0 To $iNumElem - 1
        ;#1  $arr[0][0][0]  --> 0 0 0
        $sAns &= "#" & $i + 1 & @TAB & "arr"
        For $j = 1 To UBound($arr, 0)
            $iVal = Mod(Int($i / ($iNumElem / ($aNumElem[$j - 1]))), UBound($arr, $j))
            $sAns &= "[" & $iVal & "]"
        Next
        $sAns = $sAns & "  --> "
        For $j = 1 To UBound($arr, 0)
            $iVal = Mod(Int($i / ($iNumElem / ($aNumElem[$j - 1]))), UBound($arr, $j))
            $sAns &= $iVal & " "
        Next
        $sAns &= @CRLF
    Next
    Return $sAns
EndFunc   ;==>_ArrayContains


#cs ; Returns:-
$arr1[2]
#1    arr[0]  --> 0
#2    arr[1]  --> 1

==================
$arr2[2][4]
#1    arr[0][0]  --> 0 0
#2    arr[0][1]  --> 0 1
#3    arr[0][2]  --> 0 2
#4    arr[0][3]  --> 0 3
#5    arr[1][0]  --> 1 0
#6    arr[1][1]  --> 1 1
#7    arr[1][2]  --> 1 2
#8    arr[1][3]  --> 1 3

==================
$arr3[2][4][3]
#1    arr[0][0][0]  --> 0 0 0
#2    arr[0][0][1]  --> 0 0 1
#3    arr[0][0][2]  --> 0 0 2
#4    arr[0][1][0]  --> 0 1 0
#5    arr[0][1][1]  --> 0 1 1
#6    arr[0][1][2]  --> 0 1 2
#7    arr[0][2][0]  --> 0 2 0
#8    arr[0][2][1]  --> 0 2 1
#9    arr[0][2][2]  --> 0 2 2
#10    arr[0][3][0]  --> 0 3 0
#11    arr[0][3][1]  --> 0 3 1
#12    arr[0][3][2]  --> 0 3 2
#13    arr[1][0][0]  --> 1 0 0
#14    arr[1][0][1]  --> 1 0 1
#15    arr[1][0][2]  --> 1 0 2
#16    arr[1][1][0]  --> 1 1 0
#17    arr[1][1][1]  --> 1 1 1
#18    arr[1][1][2]  --> 1 1 2
#19    arr[1][2][0]  --> 1 2 0
#20    arr[1][2][1]  --> 1 2 1
#21    arr[1][2][2]  --> 1 2 2
#22    arr[1][3][0]  --> 1 3 0
#23    arr[1][3][1]  --> 1 3 1
#24    arr[1][3][2]  --> 1 3 2

==================
#ce
Link to comment
Share on other sites

@Malkey, your code is very cool too! My firsts scripts to solve this problem use function Mod, like you.

I got close, but you come on target, contratulations too!

Their help was greatly appreciated also, realy thank you!

Br Detefon

Visit my repository

Link to comment
Share on other sites

Hum... I was hungry...

Another example...

#include <Array.au3>

Global $aTypes[5] = ['Jam', 'Jelly', 'Butter', 'Membrillo', 'Marmalade']
Global $aIntense[10] = ['', 'light', 'dark', 'forest', 'lawn', 'lime', 'sea', 'medium', 'pale', 'spring']
Global $aColors[16] = ['White', 'Black', 'Red', 'Blue', 'Yellow', 'Green', 'Orange', 'Purple', 'Pink', 'Gray', 'Silver', 'Brown', 'Gold', 'Lime', 'Violet', 'Magenta']
Global $aFruit[44] = ['Blackberry', 'Blueberry', 'Grapes', 'Kiwi', 'Strawberry', 'Rapberry', 'Cherries', 'Plums', 'Apricots', 'Nectarines', 'Peaches', 'Tropical', 'Yellow Cavendish', 'Chunkey bananas', 'Manzano', 'Plantain', 'Star Fruit', 'Pomegranade', 'Coconut', 'Fig', 'Green Papaya', 'Papaya', 'Mango', 'Persimmon', 'Pineapple', 'Cashew', 'Guava', 'Jackfruit', 'Litchi', 'Passion Fruit', 'Tamarind', 'Melons', 'Casaba Melon', 'Cantaloupe', 'Watermelon', 'Apple', 'Pear', 'Quince', 'Dried Fruit', 'Currants', 'Raisins', 'Golden raisins', 'Prunes', 'Dried Bananas']

Global $nham[5][10][16][44]
For $ii = 0 To 4
    For $jj = 0 To 9
        For $kk = 0 To 15
            For $ll = 0 To 43
                $nham[$ii][$jj][$kk][$ll] = $aTypes[$ii] & "'s " & $aIntense[$jj] & ' ' & $aColors[$kk] & ' ' & $aFruit[$ll]
            Next
        Next
    Next
Next

_Combinations($nham)

Func _Combinations($arr)
    Local $i = 0
    Local $iCount = 1

    While 1
        $i += 1
        $iLen = UBound($arr, $i)
        If $iLen = 0 Then ExitLoop

        $iCount *= $iLen
    WEnd

    Local $aResult[$iCount]
    Local $iDims = $i - 1
    Local $iSwap = $iCount
    Local $iIndex, $iVal

    For $i = 0 To $iDims - 1
        $iSwap /= UBound($arr, $i + 1)
        $iIndex = 0
        $iVal = 0

        For $j = 0 To $iCount - 1
            If $iIndex = $iSwap Then
                $iIndex = 0
                If $iVal = UBound($arr, $i + 1) - 1 Then
                    $iVal = 0
                Else
                    $iVal += 1
                EndIf
            EndIf
            $aResult[$j] &= '[' & $iVal & ']'
            $iIndex += 1
        Next
    Next
    For $each In $aResult
        ConsoleWrite('$arr' & $each & '=' & Execute('$arr' & $each) & @LF)
    Next

    ;Return $aResult
EndFunc   ;==>_Combinations

Visit my repository

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...