Scramble a string with conditions

kelly mort

Well-known Member
Joined
Apr 10, 2017
Messages
1,796
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
 

Some videos you may like

Excel Facts

Format cells as currency
Select range and press Ctrl+Shift+4 to format cells as currency. (Shift 4 is the $ sign).

footoo

Well-known Member
Joined
Sep 21, 2016
Messages
3,049
Office Version
  1. 2016
Platform
  1. Windows
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
 

kelly mort

Well-known Member
Joined
Apr 10, 2017
Messages
1,796
Office Version
  1. 2016
Platform
  1. Windows
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:

kelly mort

Well-known Member
Joined
Apr 10, 2017
Messages
1,796
Office Version
  1. 2016
Platform
  1. Windows
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?
 

footoo

Well-known Member
Joined
Sep 21, 2016
Messages
3,049
Office Version
  1. 2016
Platform
  1. Windows

ADVERTISEMENT

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
 

kelly mort

Well-known Member
Joined
Apr 10, 2017
Messages
1,796
Office Version
  1. 2016
Platform
  1. Windows
@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:

footoo

Well-known Member
Joined
Sep 21, 2016
Messages
3,049
Office Version
  1. 2016
Platform
  1. Windows

ADVERTISEMENT

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
 

kelly mort

Well-known Member
Joined
Apr 10, 2017
Messages
1,796
Office Version
  1. 2016
Platform
  1. Windows
Exactly what I am looking for.

Thanks so much.

I will like to understand it more. Can you help with some notes on that?
 

footoo

Well-known Member
Joined
Sep 21, 2016
Messages
3,049
Office Version
  1. 2016
Platform
  1. Windows
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:

footoo

Well-known Member
Joined
Sep 21, 2016
Messages
3,049
Office Version
  1. 2016
Platform
  1. Windows
These 2 lines:
Code:
com = Get_Comb("", "", str)
ray = Remove_Dup(Split(com, ","))
Could be combined:
Code:
ray = Remove_Dup(Split(Get_Comb("", "", str), ","))
 

Watch MrExcel Video

Forum statistics

Threads
1,108,974
Messages
5,525,990
Members
409,673
Latest member
Riseee

This Week's Hot Topics

Top