After my previous submission (Maths Revision V1.0) in the TechNet competition last month, here's a preview of what V2.0 will contain:



Download: char Combinations.zip

When answering a forum question on how to calculate the shortest path from form left to right, intersecting 4 ellipses, where I had to find every possible order for the 4 ellipses before measuring the distances for each unique path, I developed some code to find every possible order. It hadn't occurred to me before that the number of unique paths is equal to the factorial of the number of ellipses (4! = 24). This is the code I developed for finding every possible combination of a user defined set of characters:

Imports System.Numerics
 
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.AcceptButton = Button1
    End Sub
 
    'this draws a grid over the whole form
    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        For c As Integer = 0 To Me.Width Step 25
            e.Graphics.DrawLine(Pens.LightGray, c, 0, c, Me.Height)
        Next
        For r As Integer = 0 To Me.Height Step 25
            e.Graphics.DrawLine(Pens.LightGray, 0, r, Me.Width, r)
        Next
    End Sub
 
    Private Function listCombinations(ByVal n As Integer, ByVal a() As Object) As List(Of String)
        Dim output As New List(Of String)
        Dim max As BigInteger = Factorial(n)
        Dim counter As New BigInteger(0)
        Dim ordinals(n - 1) As Integer
        ordinals.SetValue(-1, ordinals.GetUpperBound(0))
        Do While counter < max
            incrementOrdinals(n - 1, ordinals)
            If ordinals.Distinct.Count <> ordinals.Count Then Continue Do
            counter += 1
            output.Add(String.Concat(ordinals.Select(Function(x) a(x))))
        Loop
        Return output
    End Function
 
    Private Function Factorial(n As Integer) As BigInteger
        Dim f As New BigInteger(n)
        For x As Integer = n - 1 To 1 Step -1
            f = f * x
        Next
        Return f
    End Function
 
    Private Sub incrementOrdinals(max As Integer, ByRef o() As Integer)
        For x As Integer = max To 0 Step -1
            If o(x) < max Then
                o(x) += 1
                Exit For
            Else
                o(x) = 0
            End If
        Next
    End Sub
 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If TextBox1.Text.Length = 1 Then
            If Char.IsLetterOrDigit(TextBox1.Text, 0) Then
                ListBox2.Items.Add(TextBox1.Text)
                TextBox1.Clear()
                ListBox1.Items.Clear()
                ListBox1.Items.AddRange(listCombinations(ListBox2.Items.Count, ListBox2.Items.Cast(Of String).ToArray).ToArray)
                Label1.Text = String.Format("Combinations: {0}", ListBox1.Items.Count)
            End If
        End If
    End Sub
 
    Private Sub ListBox2_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles ListBox2.MouseDoubleClick
        Dim clickedIndex As Integer = ListBox2.IndexFromPoint(e.Location)
        If clickedIndex > -1 Then
            ListBox2.Items.RemoveAt(clickedIndex)
            ListBox1.Items.Clear()
            If ListBox2.Items.Count > 0 Then
                ListBox1.Items.AddRange(listCombinations(ListBox2.Items.Count, ListBox2.Items.Cast(Of String).ToArray).ToArray)
            End If
            Label1.Text = String.Format("Combinations: {0}", ListBox1.Items.Count)
        End If
    End Sub
 
End Class