// [snippet:Using declared functions] let range = [0..999] let condition x = x % 3 = 0 || x % 5 = 0 range |> List.filter condition |> List.fold (+) 0 // [/snippet] // [snippet: Using lambda functions] [0..999] |> Seq.filter (fun x -> x % 3 = 0 || x % 5 = 0) |> Seq.reduce (+) // [/snippet] // [snippet: Using sequence expressions] seq { for x in 0 .. 999 do if x % 3 = 0 || x % 5 = 0 then yield x } |> Seq.sum // [/snippet] // [snippet: Using recursive function for ultimate speed] let rec multiple x = if x = 1000 then 0 elif x%3 = 0 || x%5 = 0 then x + multiple (x+1) else multiple (x+1) multiple 1 // [/snippet] // [snippet: Using accumulator for tail-recursive and pattern matching] let rec mul' acc x = match x with | 999L -> acc + x | x when (x%3L=0L||x%5L=0L) -> mul' (acc + x) (x + 1L) | _ -> mul' acc (x + 1L) mul' 0L 1L // [/snippet] //[snippet: Fast calculation (generalized solution)] let mSum (multipliers:int list) limit = //if 1 + 2 + .. + n = n*(n+1)/2 let aSum n = n*(n+1I) >>> 1 //then k + 2k + .. + k*n = k*(aSum n), where n = limit/k let lSum limit k = limit/k |> aSum |> (*) k //make all combinations of multipliers //thanks to Alexander Rautenberg let allCombinations lst = let rec comb accLst elemLst = match elemLst with | h::t -> let next = [h]::List.map (fun el -> h::el) accLst @ accLst comb next t | _ -> accLst comb [] lst //and do calculations using inclusion–exclusion principle multipliers |> allCombinations |> List.map (fun l -> let k = List.reduce (*) l |> bigint in if (List.length l) % 2 = 0 then -(lSum limit k) else lSum limit k ) |> List.sum let ans = mSum [3; 5] 999I //[/snippet]