Sure thing…
Excel/VBA typically limits integers to 12 or 13 digits, and then slips into e-notation. I’ve seen online mentions that the Excel datatype “Currency” can handle numbers up to 15 digits long without loss of precision brought on by e-notation; but that is still far short of my 10,000 digits or more!
I’ve tested my method out to 12,000 places, but my PC started acting a little weird; cursor/mouse/keyboard-freeze and stuff like that. I don’t know where the break-point is, but 10,000 acted up only once when I was running other programs with it; browser sessions for example. When running Excel alone, 10,000 has been stable.
The good news is that Excel/VBA can handle VERY large String (text) variables; something like 2 billion characters, although you’d likely run into other memory issues on a PC with such long strings.
So, to the point…
My code uses a simple looping process to build a seed (or starting) string of random digits of a length I specify, say 10k or anything all the way down to 1. I then apply the Collatz Odd/Even rules to iterate the process to 1. (Maybe someday to I’ll go to infinity and beyond, or into a loop other than 4-2-1.)
The core process works along the length of the seed string (str1) a digit or two at a time, converting the string “integers” into numeric ones, performing the Odd or Even arithmetic, and builds the next iteration string one character at a time.
Here is the core code that builds “str2” or “str3” from “str1,” which then becomes the new str1 for the next pass.
If str1 is even, this divides str1 by 2…
Function doeven() ’ divide by 2
str2 = “”
carry = 0
For a = 1 To Len(str1)
If InStr(“02468”, Mid(str1, a, 1)) > 0 Then ’ currdigit is even
tint = CLng(Mid(str1, a, 1))
If carry = 1 Then
tint = tint + 10
carry = 0
End If
tint = tint / 2
str2 = str2 + CStr(tint)
Else ’ currdigit is odd
tint = CLng(Mid(str1, a, 1))
If carry = 1 Then tint = tint + 10
tint = (tint - 1) / 2
carry = 1
str2 = str2 + CStr(tint)
End If
Next
str1 = str2
End Function
If str1 is odd, this performs the two-step process of (a) multiplying str1 by 3, and then (b) adding 1…
Function doodd() ’ times 3 plus 1
str2 = “”
carry = 0
For a = Len(str1) To 1 Step -1
tint = CLng(Mid(str1, a, 1)) * 3 + carry
carry = 0
If tint > 9 Then carry = 1
If tint > 19 Then carry = 2
str2 = Right(CStr(tint), 1) + str2
Next
If carry > 0 Then str2 = CStr(carry) + str2
If Mid(str2, 1, 1) = “0” Then str2 = Mid(str2, 2)
str3 = “”
carry = 0
tint = CLng(Right(str2, 1))
tint = tint + 1
If tint = 10 Then
tint = 0
carry = 1
End If
str3 = CStr(tint)
If Len(str2) > 1 Then
For a = Len(str2) - 1 To 1 Step -1
tint = CLng(Mid(str2, a, 1))
If carry = 1 Then tint = tint + 1
If tint < 10 Then carry = 0
str3 = Right(CStr(tint), 1) + str3
Next
End If
If carry = 1 Then str3 = “1” + str3
str1 = str3
End Function
That’s pretty much the whole program other than a bunch of “Dim” statements, a routine to generate random seeds of a specified length, counters, duration measurement, and output to spreadsheet cells and text file to show results.
Regarding speed… When I first thunk up this approach, I thought it would be very slow due to all the flip-flops from String to Integer to String, but it seems very fast to me in that regard. Also, I’ve done heavy lifting in the past with Java rather than VBA (as in the Eternity II puzzle) when speed was the total issue; AI told me the other day that VBA is as fast (or faster!) as Java with most functions; I don’t believe that for a millisecond!
Follow-up questions/comments are of course welcomed! If you want it, and if I can, I will send you my full exact .xlsm file (which is still a work in progress); just let me know how! At this time, I am altering the code for various reasons before running; I am in the process of putting those “controls” onto an Excel form with a “Go” button – making an easy GUI. 