User:Eriksiers/Prime numbers

From Rosetta Code

This is something I first wrote several years ago (2002, according the the copyright... I don't remember). It is VBA/Excel (Visual Basic for Applications, Excel-specific) code that calculates the factors of a series of numbers, highlighting prime numbers by turning on the cell's font.bold property. I used Excel because it's especially suited for the tabular nature of the output.

I've placed it here, in its own page, because I feel that it doesn't specifically fit any of the (current) prime number-related tasks (although part of it does demonstrate Primality by Trial Division and Prime decomposition). This could perhaps be listed on the Category:Prime Numbers page, but I'll leave that decision to someone else.

This could be improved by using run-length encoding, assuming your implementation of RLE can handle multiple-character strings. (2*2*2*11*11 -> 2^3*11^2)

(Note the Swap subroutine. It's included here because VB doesn't provide such a function itself.)

' Copyright 2002-2009 Erik Siers
' source available under terms of the GNU GPL, version 2 or
' (at your option) any later version

Sub Swap(ByRef x, ByRef y)
    Dim z
    z = x
    x = y
    y = z
End Sub

Sub findPrimes()
    ' determines prime numbers within a user-entered range
    Dim prime As Boolean, neg As Boolean
    Dim thisRow As Long, thisNumber As Long, startCol As Long, startRow As Long
    Dim m As String, n As String, outP As String
    Dim i As Long, j As Long

    prime = True    ' true until proven false
    startCol = ActiveCell.Column
    startRow = ActiveCell.Row
    thisRow = startRow - 1
    m = InputBox("Starting number?", "Enter a whole number")
    startVal = Int(Val(m))
    n = InputBox("Ending number?", "Enter a whole number")
    endVal = Int(Val(n))
    If endVal < startVal Then Swap startVal, endVal
    For i = startVal To endVal
        thisRow = thisRow + 1
        outP = ""
        Select Case i
            Case Is < 0
                neg = True
                thisNumber = -i
            Case Is < 2
                outP = Trim$(Str$(i))
                neg = False
                prime = False
                GoTo badNum
            Case Else
                neg = False
                thisNumber = i
        End Select
loca:
        For j = 2 To Int(thisNumber ^ 0.5)
            If thisNumber Mod j = 0 Then
                outP = outP & "*" & Trim$(Str$(j))
                thisNumber = thisNumber / j
                prime = False
                GoTo loca
            End If
        Next
        outP = outP & "*" & Trim$(Str$(thisNumber))
        If outP = "" Then
            outP = Trim$(Str$(i))
        Else
            outP = Mid$(outP, 2)
        End If
        prime = (Val(outP) = i)
badNum:
        Cells(thisRow, startCol).Formula = Trim(Str(i))
        If neg Then outP = "-1*" & outP
        Cells(thisRow, startCol + 1).Formula = outP
        If prime And Not (neg) Then
            Cells(thisRow, startCol + 1).Font.Bold = True
        Else
            Cells(thisRow, startCol + 1).Font.Bold = False
        End If
        DoEvents
    Next
End Sub