The 3n+1 problem in VB.NET
using VS2022
🍀Introduction
3n+1 conjecture also known as the Collatz Conjecture; is an intriguing mathematical puzzle that has challenged researchers for decades.
Its simple formulation cloaks a deep complexity:
if odd, multiply it by 3 and add 1; iterate until you reach the number 1.
🧼In this tutorial, you'll learn:
How to address the 3n+1 problem using VB.NET with a modern twist: leveraging Visual Studio 2022, .NET 8.0 ClassLibrary, and a WinForms application to build a user-friendly interface.
Whether you’re a programming beginner or an experienced developer, this step-by-step guide and its accompanying code examples illustrate not only the algorithm but also how to structure your code into a reusable library.
👨🏫Understanding the 3n+1 (Collatz) Conjecture
The Collatz Conjecture states that no matter which positive integer you start with, if you iterate by applying the following rules:
If {n} is even: divide it by 2. If {n} is odd: multiply it by 3 and add 1. … then you will eventually reach the number 1.
While this is easy to state, proving or disproving the conjecture for every positive integer remains an unsolved mystery in mathematics.
🐍Project Architecture
ClassLibrary + WinForms For this solution, we are using a two-project setup in Visual Studio 2022 with .NET 8.0:
🔬 ClassLibrary Project
This project encapsulates the core algorithm for generating the Collatz sequence for any given integer. Encapsulating this logic makes your code reusable and easier to test.
🫧 WinForms Application
This project offers a friendly user interface UI. The WinForms app lets the user enter a number, invokes the ClassLibrary’s method, and displays the resulting sequence in a ListBox (or similar control).
🎁Implementing the Collatz Algorithm in a .NET 8.0 ClassLibrary
- Create a new ClassLibrary project 'CollatzSequence.vb' (VB.NET, targeting .NET 8.0) and add the following code
Imports System.IO
Imports System.Numerics
''' ''' Encapsulates Collatz (3n+1) sequence generation, statistics, and export.
''' Public Class CollatzSequence
Private ReadOnly _startValue As BigInteger
Private ReadOnly _power As Integer
Private _sequence As List(Of BigInteger)
Private _steps As Integer
Private _maxValue As BigInteger
''' Initial integer (must be ≥1).
''' Optional exponent to raise the startValue (default = 1).
Public Sub New(startValue As BigInteger, Optional power As Integer = 1)
If startValue < 1 Then Throw _
New ArgumentOutOfRangeException(NameOf(startValue),
"Start value must be ≥ 1.")
If power < 1 Then Throw New ArgumentOutOfRangeException(NameOf(power),
"Power must be ≥ 1.")
_startValue = BigInteger.Pow(startValue, power)
_power = power
_sequence = New List(Of BigInteger) From {_startValue}
_maxValue = _startValue
_steps = 0
End Sub
''' ''' Runs the Collatz iteration until it reaches 1,
''' recording each intermediate value.
''' Public Sub Compute()
Dim current As BigInteger = _startValue
Do While current <> 1
If current Mod 2 = 0 Then
current /= 2 ' Even step: n / 2
Else
current = (current * 3) + 1 ' Odd step: 3n + 1
End If
_sequence.Add(current)
_steps += 1
If current > _maxValue Then _maxValue = current
Loop
End Sub
''' All values in the sequence, including the start and 1 at the end.
Public ReadOnly Property Sequence As IReadOnlyList(Of BigInteger)
Get
Return _sequence.AsReadOnly()
End Get
End Property
''' Number of steps taken to reach 1.
Public ReadOnly Property Steps As Integer
Get
Return _steps
End Get
End Property
''' Greatest value encountered in the sequence.
Public ReadOnly Property MaxValue As BigInteger
Get
Return _maxValue
End Get
End Property
''' ''' Returns the sequence as a single space‑delimited string.
''' Public Function ToDelimitedString(delimiter As String) As String
Return String.Join(delimiter, _sequence)
End Function
''' ''' Saves the sequence to a file in CSV format: start on first line, then delimited values.
''' ''' Full path to the .csv or .txt file.
''' Delimiter to separate values (e.g. ";" for CSV).
''' If True, appends to existing file; otherwise overwrites.
Public Sub SaveToFile(filePath As String, delimiter As String, append As Boolean)
Dim header = $"({_startValue})"
Dim body = ToDelimitedString(delimiter)
If append AndAlso File.Exists(filePath) Then
File.AppendAllText(filePath, header & vbCrLf & body & vbCrLf)
Else
File.WriteAllText(filePath, header & vbCrLf & body & vbCrLf)
End If
End Sub
End Class
This code defines a routine called GetCollatzSequence which returns a list of integers representing the sequence of numbers starting with the given input {n} until 1 is reached. - Design your Form 'Form1.vb' with these basic controls:
- TextBox controls named txtInput,txtPwr,txtCnt,txtBig,txtReslts,txtOutputs for entering the starting number, {n} to the Power of {x}, the highest result, the sum of all resultsm, the sequence of results until reaching number 1.
- Button controls named btnCalculate,btnReset,btnSaveCSV,btnSaveTxt.
- Progressbar control, BackGroundWorker control
- Optionally, TextBox controls txtCntOdd,txtCntEven to display count od odd numbers and count of even numbers within the result.
Imports System.ComponentModel
Imports System.Numerics
Imports System.Windows.Forms.VisualStyles
Imports System.Windows.Forms.VisualStyles.VisualStyleElement
Imports CollatzSequence
Public Class Form1
Private Sub Lblinfo_Click_1(sender As Object, e As EventArgs) Handles Lblinfo.Click
Process.Start(New ProcessStartInfo With {
.FileName = "https://adonetaccess2003.blogspot.com/vbnet-3nplus1-collatz-tutorial.html",
.UseShellExecute = True
})
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
KeyPreview = True
Lblinfo.Cursor = Cursors.Hand
TxtCnt.ReadOnly = True
TxtBig.ReadOnly = True
TxtOdd.ReadOnly = True
TxtEven.ReadOnly = True
TxtSum.ReadOnly = True
With ProgressBar1
.Style = ProgressBarStyle.Continuous
.Minimum = 0
.Maximum = 100
End With
With BackgroundWorker1
.WorkerReportsProgress = True
.WorkerSupportsCancellation = True
End With
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Escape Then Close()
End Sub
Private Sub CalcBtn_Click(sender As Object, e As EventArgs) Handles CalcBtn.Click
Dim pwr As Integer = If(String.IsNullOrWhiteSpace(TxtPwr.Text), 1, _
Integer.Parse(TxtPwr.Text))
If BackgroundWorker1.IsBusy Then Return
ProgressBar1.Value = 0
BackgroundWorker1.RunWorkerAsync()
'' Read inputs
'Dim start As BigInteger = BigInteger.Parse(TxtInput.Text)
'' Initialize and compute
'Dim collatz = New CollatzSequence.CollatzSequence(start, pwr)
'collatz.Compute()
'' Display results
'TxtOutputs.Text = collatz.ToDelimitedString(" ")
'TxtCnt.Text = collatz.Steps.ToString()
'TxtBig.Text = collatz.MaxValue.ToString()
End Sub
Private Sub BtnCsv_Click(sender As Object, e As EventArgs) Handles BtnCsv.Click
If String.IsNullOrEmpty(TxtOutputs.Text) Then Exit Sub
Dim path = IO.Path.Combine(Application.StartupPath, "MyTest.csv")
Dim collatz = New CollatzSequence.CollatzSequence(BigInteger.Parse(TxtInput.Text), _
Integer.Parse(TxtPwr.Text))
collatz.Compute()
collatz.SaveToFile(path, ";", append:=True)
MessageBox.Show("Saved!")
End Sub
Private Sub BtnTxt_Click(sender As Object, e As EventArgs) Handles BtnTxt.Click
If String.IsNullOrEmpty(TxtOutputs.Text) Then Exit Sub
Dim path = IO.Path.Combine(Application.StartupPath, "MyTest.txt")
Dim collatz = New CollatzSequence.CollatzSequence(BigInteger.Parse(TxtInput.Text), _
Integer.Parse(TxtPwr.Text))
collatz.Compute()
collatz.SaveToFile(path, ";", append:=True)
MessageBox.Show("Saved!")
End Sub
Private Sub BtnReset_Click(sender As Object, _
e As EventArgs) Handles BtnReset.Click
TxtBig.Clear()
TxtCnt.Clear()
TxtInput.Clear()
TxtOutputs.Clear()
TxtPwr.Clear()
TxtBig.Clear()
TxtEven.Clear()
TxtSum.Clear()
ProgressBar1.Value = 0
End Sub
Private Sub TxtInput_KeyPress(sender As Object, _
e As KeyPressEventArgs) Handles TxtInput.KeyPress
If Not Char.IsNumber(e.KeyChar) AndAlso Not Char.IsControl(e.KeyChar) Then
e.Handled = True
End If
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, _
e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim input As BigInteger = BigInteger.Parse(TxtInput.Text)
If Len(TxtPwr.Text) >= 1 Then
input = BigInteger.Pow(CInt(TxtInput.Text), CInt(TxtPwr.Text))
End If
Dim results As New List(Of BigInteger)
Dim current As BigInteger = input
Dim steps As Integer = 0
Dim maxVal As BigInteger = current
Dim SumAll As BigInteger = current ' start with the initial value
Dim OddCount As Integer = 0
Dim EvenCount As Integer = 0
Do Until current = 1
If current Mod 2 = 0 Then
current = current / 2
EvenCount += 1 ' Increment even counter
Else
current = (current * 3) + 1
OddCount += 1 ' Increment odd counter
End If
results.Add(current)
steps += 1
If current > maxVal Then maxVal = current
SumAll += current ' accumulate into sum
' Simulate progress
If steps Mod 10 = 0 Then
Dim progressPercent As Integer = CInt((steps Mod 1000) / 1000.0 * 100)
BackgroundWorker1.ReportProgress(Math.Min(progressPercent, 100))
End If
Loop
' Package result
e.Result = New With {
.Odd = OddCount,
.Even = EvenCount,
.list = results,
.Count = steps,
.MAX = maxVal,
.Sum = SumAll
}
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
ProgressBar1.Value = e.ProgressPercentage
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Dim result = CType(e.Result, Object)
TxtOutputs.Text = String.Join(" ", CType(result.List, List(Of BigInteger)))
TxtCnt.Text = result.Count.ToString()
TxtBig.Text = result.Max.ToString()
TxtOdd.Text = result.Odd.ToString()
TxtEven.Text = result.Even.ToString()
TxtSum.Text = result.Sum.ToString() ' display the sum
ProgressBar1.Value = 100
End Sub
Private Sub TxtPwr_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtPwr.KeyDown
If e.KeyCode = Keys.Return Then
If String.IsNullOrWhiteSpace(TxtPwr.Text) Then
MessageBox.Show("Please enter a power value.")
TxtPwr.Focus()
Return
End If
Call CalcBtn_Click(sender, e)
End If
End Sub
Private Sub TxtInput_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtInput.KeyDown
If e.KeyCode = Keys.Return Then
If String.IsNullOrWhiteSpace(TxtInput.Text) Then
MessageBox.Show("Please enter a number.")
TxtInput.Focus()
Return
End If
Call CalcBtn_Click(sender, e)
End If
End Sub
End Class
💬Computation Logic
The BackgroundWorker1_DoWork method manually implements the Collatz sequence algorithm:
It parses the input {n} from TxtInput.Text and applies the power from TxtPwr.Text using BigInteger.Pow.
It iterates the Collatz rules (n / 2 for even, 3n + 1 for odd) until reaching 1.
It tracks the sequence (results), steps, maximum value, sum, and counts of odd and even steps.
💽Output result example
Using Collatz Conjecture, calculate:
Twenty seven 27 to the power of ^ twenty seven 27 {27^27}
📅Outputs
♥ Here are some online Visual Basic lessons and courses:
No comments:
Post a Comment