HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Project Euler #1-3 in VBA

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
projecteulervba

Problem

Self explanatory, and all the functions contain descriptions of their specific problem statements.

Since this is project Euler, I would be particularly interested in any analysis of the functions' computational efficiency.

```
Option Explicit

Public Function ProjectEuler1() As Long

'/ Problem statement: sum all multiples of 3 and 5 from 1 to 999

Dim total As Long
Dim i As Long

For i = 1 To 999

If i Mod 3 = 0 Or i Mod 5 = 0 Then

total = total + i

End If

Next i

ProjectEuler1 = total

End Function

Public Function ProjectEuler2() As Long

'/ Problem statement: sum all even Fibonacci numbers below 4 Million

Dim fiboA As Long, fiboB As Long, currentFibo As Long '/ alternating fibonacci numbers
Dim bIsHigher As Boolean

fiboA = 1
fiboB = 1
currentFibo = 2

Dim total As Long

Do While currentFibo
'/ I decided to generalise it

Dim i As Long
Dim sqrtLimit As Long
Dim partiallyFactorisedNum As Long
Dim largestPrimeDivisor As Long

sqrtLimit = Application.Floor(numToFactorise ^ 0.5, 1)
partiallyFactorisedNum = numToFactorise

i = 2
If partiallyFactorisedNum Mod i = 0 Then
largestPrimeDivisor = i
partiallyFactorisedNum = KeepDividingWhileInt(partiallyFactorisedNum, i)
End If

i = 3
Do While i largestPrimeDivisor Then largestPrimeDivisor = partiallyFactorisedNum
ProjectEuler3 = largestPrimeDivisor

End Function

Public Function isPrime(ByVal numTocheck As Long)

Dim i As Long
Dim sqrtLimit As Long
sqrtLimit = Application.Floor(numTocheck ^ 0.5, 1)

isPrime = True

If numTocheck Mod 2 = 0 And numTocheck <> 2 Then isPrime = False

i = 3
Do While i <= sqrtLimit And isPrime
If numTocheck Mod i = 0 Then isPrime = False
i = i + 2
Loop

End Function

Public Function Ke

Solution

While quickly running over your code, my eyes stopped on your function KeepDividingWhileInt.

It seemed over-complicated.

Let's write what it does:

  • Creates isDivisible



  • Sets isDivisible to true



  • Loops while isDividible is true:



  • If numToDivide Mod divisor is 0



  • Divides numToDivide by divisor



  • Else



  • Sets isDivisible to false



  • Returns numToDivide



Well, there is a subtle bug on step 2: You assume that the number is divisible by divisor, which may not be true (e.g.: KeepDividingWhileInt(3,2)).

Also, the whole code could be extremely simplified, by moving the condition inside that if into the while.

Also, you could try to use While ... Wend instead of Do While ... Loop, as suggested by @Mat's Mug. This point actually applies everywhere on your code.

The final result:

Public Function KeepDividingWhileInt(ByVal numToDivide As Long, ByVal divisor As Long) As Long

While numToDivide Mod divisor = 0
numToDivide = numToDivide / divisor
Wend

KeepDividingWhileInt = numToDivide

End Function


Oh my! The function is so simple that you can read it in a single sentence:


Divide numToDivide by divisor while the reminder is 0, returning the final result.

So simple, right?

Context

StackExchange Code Review Q#112822, answer score: 4

Revisions (0)

No revisions yet.