Highly Modular FizzBuzz
open System
type FBRuleType =
| MultipleOf of int
| After of int
| Before of int
| EqualTo of int
| CustomRule of (int -> bool)
| Or of FBRuleType list
| And of FBRuleType list
type FBRule = FBRuleType * string
let determineFB num rule =
let rec loop rl =
match rl with
| MultipleOf i -> num % i = 0
| After i -> num > i
| Before i -> num < i
| EqualTo i -> num = i
| CustomRule fn -> fn num
| Or lis ->
lis
|> List.map (fun r -> loop r)
|> List.contains true
| And lis ->
lis
|> List.map (fun r -> loop r)
|> List.contains false
|> not
loop rule
let FBString num (rules: FBRule list) =
List.fold (fun acc i ->
match i with
| (rule, value) ->
if determineFB num rule then
acc + value
else acc
) "" rules
let calcFB num rules =
match FBString num rules with
| "" -> string num
| a -> a
let runRuleset ruleset =
printfn "\n\nTesting ruleset %A" ruleset
for i in 1..75 do
calcFB i ruleset |> printfn "%s"
runRuleset [(MultipleOf 3, "Fizz"); (MultipleOf 5, "Buzz")]
runRuleset [(MultipleOf 3, "Fizz"); (MultipleOf 5, "Buzz"); (And [MultipleOf 4; After 10], "Wack")]
runRuleset [(Or [MultipleOf 4; And [MultipleOf 3; MultipleOf 5]], "Hey"); (CustomRule (fun i -> i % 4 = 0 || (i % 3 = 0 && i % 5 = 0)), "Now")]
runRuleset [(Or [MultipleOf 3; EqualTo 10; And [After 50; MultipleOf 2]; Or [Before 5; EqualTo 5; MultipleOf 10]], "Wow")]
|
run
| edit
| history
| help
|
0
|
|
|