[Solved] Combinations items

William Lancee

Well-Known Member
Licensed User
Longtime User
Note that the number of rows in the result list goes up exponentially with the number of positions.
10 positions with 3 possible values in each position yields 59048 rows.

Also note that if the number of values are different for each position, the algorithm will need to be tweaked.
It will still work but more infrastructure will need to be added for the different 'bases'.

Note also that the actually values (in this example: man, dog, cat) can be anything and can be different for each position.
That is just the display part and is independent of the algorithm.
 

William Lancee

Well-Known Member
Licensed User
Longtime User
After some tweaking, a generalized efficient permutations algorithm.

B4X:
Private Sub Permutations(values As List) As List
    Dim results As List
    results.Initialize
    Dim positions As Int = values.Size
    Dim d(positions + 1) As Int
    d(0) = 1
    For j = 1 To d.length - 1
        Dim v() As String = values.Get(positions - j)
        d(j) = d(j - 1) * v.length
    Next
    
    Dim n As Int = d(values.Size) - 1
    For i = 0 To n
        Dim val As Int = i
        Dim a(positions) As Int
        For j = 0 To positions - 1
            a(j) = val / d(positions - j - 1)
            val = val - a(j) * d(positions - j - 1)
        Next
        results.Add(a)
    Next
    Return results   
End Sub

How to use...

B4X:
    Dim marker As Long = DateTime.Now

    Dim values As List
    values.Initialize
    values.Add(Array As String("1", "2", "3", "4", "5"))
    values.Add(Array As String("man", "dog", "cat"))
    values.Add(Array As String("cheese", "sprouts"))
    values.Add(Array As String("chevy", "ford", "dodge", "lancia"))
    Dim results As List = Permutations(values)

    Log(DateTime.Now - marker)    '<1 msec

    'Display results   
    Dim sb As StringBuilder
    For Each a() As Int In results
        sb.Initialize
        For j = 0 To values.Size - 1
            Dim strValues() As String = values.Get(j)
            sb.Append(strValues(a(j))).Append(TAB)
        Next
        Log(sb.ToString)
    Next
    '1    man    cheese    chevy
    '1    man    cheese    ford
    '1    man    cheese    dodge
    '1    man    cheese    lancia
    '1    man    sprouts    chevy
    '1    man    sprouts    ford
    '1    man    sprouts    dodge
    '1    man    sprouts    lancia
    '1    dog    cheese    chevy
    '.....
    '5    cat    sprouts    lancia
 
Top