I have this code written for a Project Euler problem in c++:
int sum = 0;
for(int i =0; i < 1000; i++)
{
//Check if multiple of 3 but not multiple of 5 to prevent duplicate
sum += i % 3 == 0 && i % 5 != 0 ? i: 0;
//check for all multiple of 5, including those of 3
sum += i % 5 == 0 ? i: 0;
}
cout << sum;
I’m trying to learn f# and rewriting this in f#. This is what I have so far:
open System
//function to calculate the multiples
let multiple3v5 num =
num
//function to calculate sum of list items
let rec SumList xs =
match xs with
| [] -> 0
| y::ys -> y + SumList ys
let sum = Array.map multiple3v5 [|1 .. 1000|]
What I have may be complete nonsense…so help please?
Your
sumListfunction is a good start. It already iterates (recursively) over the entire list, so you don’t need to wrap it in an additionalArray.map. You just need to extend yoursumListso that it adds the number only when it matches the specified condition.Here is a solution to a simplified problem – add all numbers that are divisible by 3:
This is the basic way of writing the function using explicit recursion. In practice, the solution by jpalmer is how I’d solve it too, but it is useful to write a few recursive functions yourself if you’re learning F#.
The accumulator parameter mentioned by sashang is a more advanced way to write this. You’ll need to do that if you want to run the function on large inputs (which is likely the case in Euler problem). When using accumulator parameter, the function can be written using tail recursion, so it avoids stack overflow even when processing long lists.
The idea of a accumulator-based version is that the function takes additional parameter, which represents the sum calculated so far.
When you call it initially, you write
sumList [ ... ] 0. The recursive calls will not cally + sumList xs, but will instead addyto the accumulator and then make the recursive callsumList xs (y + sumSoFar). This way, the F# compiler can do tail-call optimization and it will translate code to a loop (similar to the C++ version).