patternMinor
Project Euler #1-3 in VBA
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
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
It seemed over-complicated.
Let's write what it does:
Well, there is a subtle bug on step 2: You assume that the number is divisible by
Also, the whole code could be extremely simplified, by moving the condition inside that
Also, you could try to use
The final result:
Oh my! The function is so simple that you can read it in a single sentence:
Divide
So simple, right?
KeepDividingWhileInt.It seemed over-complicated.
Let's write what it does:
- Creates
isDivisible
- Sets
isDivisibletotrue
- Loops while
isDividibleistrue:
- If
numToDivide Mod divisoris0
- Divides
numToDividebydivisor
- Else
- Sets
isDivisibletofalse
- 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.