Run Code  | API  | Code Wall  | Misc  | Feedback  | Login  | Theme  | Privacy  | Patreon 

Highly Modular FizzBuzz

//F# Compiler for F# 4.0 (Open Source Edition), Mono 4.2.1

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 = //Determines if a number matches a given rule type
    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) = //Matches a number to a list of rules
    List.fold (fun acc i -> 
        match i with 
        | (rule, value) ->
            if determineFB num rule then
                acc + value
            else acc
        ) "" rules

let calcFB num rules = //Determines if a rule was matched or not
    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")] //%3 -> Fizz; %5 -> Buzz
runRuleset [(MultipleOf 3, "Fizz"); (MultipleOf 5, "Buzz"); (And [MultipleOf 4; After 10], "Wack")] //%3 -> Fizz; %5 -> Buzz; (%4 & >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")] //(%4 | (%3 & %5)) -> Hey; (%4 | (%3 & %5)) -> Now
runRuleset [(Or [MultipleOf 3; EqualTo 10; And [After 50; MultipleOf 2]; Or [Before 5; EqualTo 5; MultipleOf 10]], "Wow")] //(%3 | =10 | (>50 & %2) | (<5 | =5 | %10)) -> Wow
 run  | edit  | history  | help 0