Scramble a string with conditions

kelly mort

Well-known Member
Joined
Apr 10, 2017
Messages
2,169
Office Version
  1. 2016
Platform
  1. Windows
I want to scramble a given string then store the various combinations to a variable or an array based on what you think is cool for my demand. I came across this pieces but they are not exactly what I wanted.




Now this is what I wanna achieve; my code will take a string in the form “AABB” eg 0011, 1122 ,….. Then scramble the string making sure there is no output in the form “AABB” or “BBAA”
So for 0011, the output will be 0101, 1010, 0110, 1001. Then I store this output to a variable or an array as before. The reason being that I will later use the output by splitting the output. But don’t worry about that part that much. I have a way of dealing with things like that. Now all I need is how to get the output and then store them in the aforementioned containers, separated by any suitable list separator. I prefer a comma.


Thanks in advance


Code:
Function Helper(s As String, Optional delim As String = ",") As String
    Dim i As Long, n As Long
    Dim t As String, c As String
    Dim A As Variant


    If Memory.exists(s) Then
        Helper = Memory(s)
        Exit Function
    End If


    'otherwise:
    'Check Basis Case:


    If Len(s) <= 1 Then
        Helper = s
    Else
        n = Len(s)
        ReDim A(1 To n)
        For i = 1 To n
            c = Mid(s, i, 1)
            t = Replace(s, c, "")
            A(i) = Helper(t, delim)
            A(i) = c & Replace(A(i), delim, delim & c)
        Next i
        Helper = Join(A, delim)
    End If


    'record before returning:


    Memory.Add s, Helper
End Function


Code:
Function scramble(s As String, Optional delim As String = ",") As String
    Set Memory = CreateObject("Scripting.dictionary")
    scramble = Helper(s, delim)
    Set Memory = Nothing
End Function


Code:
Sub Test()
    Dim s As String
    Dim i As Long, n As Long
    Dim A As Variant


    s = "0123"
    A = Split(scramble(s), ",")
    For i = 0 To UBound(A)
        Cells(i + 1, 1).Value = A(i)
    Next i
End Sub
 

Excel Facts

Move date out one month or year
Use =EDATE(A2,1) for one month later. Use EDATE(A2,12) for one year later.
Code:
Dim x$, f$, s$, a$, b$, c$, d$, combin$
x = "AABB"
f = Left(x, 1)
s = Mid(x, 3, 1)
a = f & s & f & s
b = f & s & s & f
c = s & f & f & s
d = s & f & s & f
combin = a & "," & b & "," & c & "," & d
 
Upvote 0
Code:
Dim x$, f$, s$, a$, b$, c$, d$, combin$
x = "AABB"
f = Left(x, 1)
s = Mid(x, 3, 1)
a = f & s & f & s
b = f & s & s & f
c = s & f & f & s
d = s & f & s & f
combin = a & "," & b & "," & c & "," & d


Great!!!

Thanks @footoo
It's very cool and simpler than I thought
 
Last edited:
Upvote 0
Code:
Dim x$, f$, s$, a$, b$, c$, d$, combin$
x = "AABB"
f = Left(x, 1)
s = Mid(x, 3, 1)
a = f & s & f & s
b = f & s & s & f
c = s & f & f & s
d = s & f & s & f
combin = a & "," & b & "," & c & "," & d

Hi

How do I get all the possible scramble combination for "ABCD" into the variable combin?
 
Upvote 0
Code:
Sub Set_String()
Call Get_Comb("", "ABCD")
End Sub


Sub Get_Comb(s1 As String, s2 As String)
Dim i%, sLen%, comb As New Collection
sLen = Len(s2)
If sLen < 2 Then
    comb.Add s1 & s2
Else
    For i = 1 To sLen
        Call Get_Comb(s1 + Mid(s2, i, 1), Left(s2, i - 1) + Right(s2, sLen - i))
    Next
End If
For i = 1 To comb.Count
    Debug.Print comb(i)
Next
End Sub
 
Upvote 0
@footoo,

Thanks for taking the time to fix it for me.

I have a few things I want to know if they could be implemented:

1. Instead of using the immediate window to display the output can it be store to a variable like you did in the first code?

2. Can we exclude the root string "ABCD" from appearing in the list of the scrambled ?

3. In situation where there appears to be duplicate scrambled items - where we have say "aabc" or "abcc" as the root string is there a way to retain just one of the duplicate?

If this is too much of task, then I will be glad you look at option 1 for me.

Regards
 
Last edited:
Upvote 0
Code:
Sub Set_String()
Dim com$, ray As Variant, i%, comb$
Dim str$: str = "ABCD"
com = Get_Comb("", "", str)
ray = Remove_Dup(Split(com, ","))
For i = LBound(ray) To UBound(ray) - 1
    comb = comb & ray(i) & ","
Next
comb = Left(comb, Len(comb) - 1)
comb = Right(comb, Len(comb) - Len(str) - 1)
End Sub


Function Get_Comb(comb As String, s1 As String, s2 As String)
Dim i%, sLen%
sLen = Len(s2)
If sLen < 2 Then
    comb = comb & s1 & s2 & ","
Else
    For i = 1 To sLen
        Call Get_Comb(comb, s1 + Mid(s2, i, 1), Left(s2, i - 1) + Right(s2, sLen - i))
    Next
End If
Get_Comb = comb
End Function


Function Remove_Dup(ray As Variant) As Variant
Dim i%, d As Object
Set d = CreateObject("Scripting.Dictionary")
For i = LBound(ray) To UBound(ray)
    If IsMissing(ray(i)) = False Then d.Item(ray(i)) = 1
Next
Remove_Dup = d.Keys
End Function
 
Upvote 0
Exactly what I am looking for.

Thanks so much.

I will like to understand it more. Can you help with some notes on that?
 
Upvote 0
Code:
Sub Set_String()
Dim com$, ray As Variant, i%, comb$
Dim str$: str = "ABCD"
[COLOR=#0000ff]'Call the Get_Comb function and assign the result to the string "com"[/COLOR]
com = Get_Comb("", "", str)
[COLOR=#0000ff]'Call the Remove_Dup function and assign the result to the array called "ray"[/COLOR]
ray = Remove_Dup(Split(com, ","))
[COLOR=#0000ff]'Assign the values stored in "ray" to the string "comb" with comma separator[/COLOR]
For i = LBound(ray) To UBound(ray) - 1
    comb = comb & ray(i) & ","
Next
[COLOR=#0000ff]'Remove the comma at the end[/COLOR]
comb = Left(comb, Len(comb) - 1)
[COLOR=#0000ff]'Remove the original root string[/COLOR]
comb = Right(comb, Len(comb) - Len(str) - 1)
End Sub


Function Get_Comb(comb As String, s1 As String, s2 As String)
[COLOR=#0000ff]'Function to get all of the character combinations of the string s2[/COLOR]
Dim i%, sLen%
sLen = Len(s2)
If sLen < 2 Then
   [COLOR=#0000ff] 'Assign each combination to the string "comb" (plus a comma)[/COLOR]
    comb = comb & s1 & s2 & ","
Else
    For i = 1 To sLen
        [COLOR=#0000ff]'Call the function again to assign the next character[/COLOR]
        Call Get_Comb(comb, s1 + Mid(s2, i, 1), Left(s2, i - 1) + Right(s2, sLen - i))
    Next
End If
Get_Comb = comb
End Function


Function Remove_Dup(ray As Variant) As Variant
[COLOR=#0000ff]'Function to remove duplicates from the array called "ray"
'Dictionary ignores duplicates[/COLOR]
Dim i%, d As Object
Set d = CreateObject("Scripting.Dictionary")
For i = LBound(ray) To UBound(ray)
    If IsMissing(ray(i)) = False Then d.Item(ray(i)) = 1
Next
Remove_Dup = d.Keys
End Function
 
Last edited:
Upvote 0
These 2 lines:
Code:
com = Get_Comb("", "", str)
ray = Remove_Dup(Split(com, ","))
Could be combined:
Code:
ray = Remove_Dup(Split(Get_Comb("", "", str), ","))
 
Upvote 0

Forum statistics

Threads
1,223,903
Messages
6,175,287
Members
452,631
Latest member
a_potato

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top