Print all the possible combinations of "X" amount of characters with "X" string length (Brute Force)

StackOverflow https://stackoverflow.com/questions/16962823

Question

I'm trying to write a word combination generator, I mean to print all the possible combinations of "X" amount of characters with "X" string length,

First of all I need to say I saw a question in StackOverFlow about exactly this problem which have a lot of answers of word generators to do exaclty this (on different languages), but please, don't mark this as duplicate or don't comment my question only to reference-me that link 'cause I've tested ALL the C# and VBNET codes of that question and really none works 100% as expected, see the combinations I need:

For example, If I have "a","b" and "c" characters, and I want to make all combinations of those characters in a string of "3" length then this is the result I expect:

' Expected result, 27 combinations:
'
' aaa
' aab
' aac
'
' aba
' abb
' abc
'
' aca
' acb
' acc
'
' baa
' bab
' bac
'
' bba
' bbb
' bbc
'
' bca
' bcb
' bcc
'
' caa
' cab
' cac
'
' cba
' cbb
' cbc
'
' cca
' ccb
' ccc

(The sort don't matter, I can sort it later.)

...But so far of that expected result this is what I could get:

'a
'aa
'aaa
'b
'bb
'bbb
'c
'cc
'ccc

I have done this time ago in two languages (Ruby and Batch) but using nested Fors (A lot of Fors together each For appending only one letter to the other For output), of course If I'm trying to do this in VBNET is to avoid the suing of a lot of Fors, and to do it in a better performance way.

In the code below you can see how I try to allocate all the combinations at RAM memory (an array) instead of writing they to the physical disk, so I want to write this code using a logic method and in a better performance way, then I want to save all the combinations "in the memory" first and thats the reason too why I don't want to use a lot of fors (the performance).

This was my last try, all is explained in comment-lines:

Public Class Form1

    Dim characters As Char()  ' Default value: {"a","b","c"}
    Dim StringLength As Int64 ' Default value: 3
    Dim TotalCombinations As Int64 ' Default value: 27
    Dim strarray(99999999) As String ' Default size: "99.999.999" million of combinations in memory (I need to confirm this from an expert).

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Dim index As Int64 = 0

    For column As Int64 = 0 To TotalCombinations - 1 ' For 0 to 26

        For Each character As Char In characters ' Characters = {"a","b","c"}

            If column < index Then
                index = 0 ' I reset index value 'cause... just experimenting things.
                Try
                    strarray(index) += characters(index)
                    RichTextBox1.Text += strarray(index) & ControlChars.NewLine
                Catch
                End Try
            Else
                Try
                    strarray(index) += characters(index)
                    RichTextBox1.Text += strarray(index) & ControlChars.NewLine
                Catch
                End Try
            End If
        Next

        index += 1

    Next

    End Sub

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        characters = sender.text.ToCharArray ' Result: {"a","b","c"}
        Calculate_Combinations() ' Result: 27
    End Sub

    Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
        StringLength = sender.value ' Result: 3
        Calculate_Combinations() ' Result: 27
    End Sub

    Private Sub Calculate_Combinations()
        Try
            TotalCombinations = ((characters.LongLength * StringLength) * StringLength) ' Result: 27
            Label1.Text = ((characters.LongLength * StringLength) * StringLength) & " number of combinations." ' Result: 27
        Catch : End Try
    End Sub

End Class

I precise help.

Was it helpful?

Solution

A wonderful solution using Linq by @pengyang that works with IEnumerables:

Private Shared Function GetCombinations(Of T)(list As IEnumerable(Of T), length As Integer) As IEnumerable(Of IEnumerable(Of T))
    If length = 1 Then
        Return list.[Select](Function(x) New T() {x})
    End If

    Return GetCombinations(list, length - 1).SelectMany(Function(x) list, Function(t1, t2) t1.Concat(New T() {t2}))
End Function

Then:

Dim result = GetCombinations("abc", 3)

Screenshot from LinqPad: http://i.imgur.com/Xgjg9bz.png

OTHER TIPS

Three nested loops

    Dim foo As String = "abc"
    For Each c1 As Char In foo
        For Each c2 As Char In foo
            For Each c3 As Char In foo
                Debug.WriteLine(String.Join("", c1, c2, c3))
            Next
        Next
    Next
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top