Sure, the time taken goes up exponentially as the number of items increases, but there are ways to reduce this when you realise that you don't have to search the entire solution space.
With permutations, for example, it is worth realising that (except for the trivial case where you only have one item) half of the permutations are merely mirror images. If we examine EdwinP's example in the original query:
1 2 3 -> 3 2 1
2 1 3 -> 3 1 2
2 3 1 -> 1 3 2
This realisation means that we can halve the time it takes to generate a complete solution. Here's a minor rewrite of sunaj's code to illustrate:
Const M = 3, N = 3
Dim Item(M) As Integer, Flag(M) As Integer, Queue(M) As Integer, Total As Long
Dim I As Integer
Dim StopPoint As Long
Sub Perm(M As Integer, N As Integer, Level As Integer)
Dim I As Integer, J As Integer, tmp As String
Static CheckPoint
If CheckPoint = StopPoint Then Exit Sub
For I = 1 To M
If (Flag(I) = 0) Then
Flag(I) = 1
Queue(Level) = I
If (Level < N) Then
Call Perm(M, N, Level + 1)
Else
Total = Total + 1
tmp = ""
For J = 1 To Level
tmp = tmp & CStr(Item(Queue(J)))
Next
List1.AddItem tmp
List1.AddItem StrReverse(tmp)
CheckPoint = CheckPoint + 1
Print
End If
Flag(I) = 0
End If
Next
End Sub
Private Sub Command1_Click()
StopPoint = factorial(M) / 2
For I = 1 To M
Item(I) = I
Next
Call Perm(M, N, 1)
End Sub
Private Function factorial(ByVal lSeed As Long) As Long
factorial = 1
Do Until lSeed = 0
factorial = factorial * lSeed
lSeed = lSeed - 1
Loop
End Function