Home > Net >  VBA Longest Collatz Sequence
VBA Longest Collatz Sequence

Time:09-02

I am writing a Sub to identify the longest Collatzs Sequenze between 1 and 1000. Since I just started learning VBA am wondering how I can add the process to count the length of each sequence.

Sub Collatz()

Dim i As Long
Dim maxSteps As Integer


    For i = 1 To 1000
    
        If i = 1 Then
            maxSteps = CInt(20.856 * Log(2))
        Else
            maxSteps = CInt(20.856 * Log(i))
        End If
    
        If i Mod 2 = 0 Then
            i = i / 2
        Else
            i = 3 * i   1
        End If
    
    Debug.Print i
    
    Next i
    
End Sub

CodePudding user response:

I am not sure what the Log is supposed to do in your example but I would write it like this:

Sub Collatz()
    Dim i As Long, j As Long
    Dim steps As Long
    Dim n As Long
    Dim maxSteps As Long

    For i = 1 To 1000
        j = i
        steps = 1
        Do Until j = 1
            If j Mod 2 = 0 Then
                j = j / 2
            Else
                j = 3 * j   1
            End If
            steps = steps   1
        Loop
        If steps > maxSteps Then
            n = i
            maxSteps = steps
        End If
    Next i
    Debug.Print n, maxSteps
End Sub

CodePudding user response:

Collatz

Option Explicit

Sub IdentifyFirstLongestCollatz()

    Const nStart As Long = 1
    Const nEnd As Long = 1000

    Dim n As Long
    Dim nCurr As Long
    Dim nMax As Long
    Dim RootNumber As Long
    
    For n = nStart To nEnd
        nCurr = CountHailstoneNumbers(n)
        If nMax < nCurr Then
            nMax = nCurr
            RootNumber = n
        End If
    Next n
    
    Debug.Print "Root Number:       " & RootNumber
    Debug.Print "Hailstone Numbers: " & nMax
    Debug.Print "Collatz Path:      " & Join(ArrCollatzPath(RootNumber), ",")
 
' Result:
' Root Number:       871
' Hailstone Numbers: 179
' Collatz Path:      871,2614,1307,3922,1961,5884,2942,1471,4414,2207,6622,3311,9934,4967,14902,7451,22354,11177,33532,16766,8383,25150,12575,37726,18863,56590,28295,84886,42443,127330,63665,190996,95498,47749,143248,71624,35812,17906,8953,26860,13430,6715,20146,10073,30220,15110,7555,22666,11333,34000,17000,8500,4250,2125,6376,3188,1594,797,2392,1196,598,299,898,449,1348,674,337,1012,506,253,760,380,190,95,286,143,430,215,646,323,970,485,1456,728,364,182,91,274,137,412,206,103,310,155,466,233,700,350,175,526,263,790,395,1186,593,1780,890,445,1336,668,334,167,502,251,754,377,1132,566,283,850,425,1276,638,319,958,479,1438,719,2158,1079,3238,1619,4858,2429,7288,3644,1822,911,2734,1367,4102,2051,6154,3077,9232,4616,2308,1154,577,1732,866,433,1300,650,325,976,488,244,122,61,184,92,46,23,70,35,106,53,160,80,40,20,10,5,16,8,4,2,1
End Sub

' A008908: 1, 2, 8, 3, 6, 9, 17, 4, 20, 7, 15, 10, 10, 18, 18,...
' The count of the numbers in the sequence
Function CountHailstoneNumbers( _
    ByVal RootNumber As Long) _
As Long
    Dim cNum As Long: cNum = RootNumber
    CountHailstoneNumbers = 1
    Do Until cNum = 1
        If cNum Mod 2 = 0 Then
            cNum = cNum / 2
        Else
            cNum = 3 * cNum   1
        End If
        CountHailstoneNumbers = CountHailstoneNumbers   1
    Loop
End Function

Function ArrCollatzPath( _
    ByVal RootNumber As Long) _
As Variant
    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
    Dim cNum As Long: cNum = RootNumber
    dict(cNum) = Empty
    Do Until cNum = 1
        'DoEvents
        If cNum Mod 2 = 0 Then
            cNum = cNum / 2
        Else
            cNum = 3 * cNum   1
        End If
        dict(cNum) = Empty
    Loop
    ArrCollatzPath = dict.Keys
End Function


Sub PrintHailstoneNumbersCount()
    Dim n As Long
    For n = 1 To 20
        Debug.Print n, CountHailstoneNumbers(n)
    Next n
' Result:
' 1             1
' 2             2
' 3             8
' 4             3
' 5             6
' 6             9
' 7             17
' 8             4
' 9             20
' 10            7
' 11            15
' 12            10
' 13            10
' 14            18
' 15            18
' 16            5
' 17            13
' 18            21
' 19            21
' 20            8
End Sub


' A006577: 0, 1, 7, 2, 5, 8, 16, 3, 19, 6, 14, 9, 9, 17, 17,...
' The number of steps to reach 1
Function CountSteps( _
    ByVal RootNumber As Long) _
As Long
    Dim cNum As Long: cNum = RootNumber
    Do Until cNum = 1
        If cNum Mod 2 = 0 Then
            cNum = cNum / 2
        Else
            cNum = 3 * cNum   1
        End If
        CountSteps = CountSteps   1
    Loop
End Function
  • Related