User:Eriksiers/Prime numbers

From Rosetta Code
Revision as of 17:57, 3 November 2009 by Eriksiers (talk | contribs) (created)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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 version) 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 should 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.)

<lang vb>' 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</lang>