Skip to content

Instantly share code, notes, and snippets.

@quangnle
Last active August 29, 2015 14:17
Show Gist options
  • Save quangnle/9a03caabd225ab7d3c98 to your computer and use it in GitHub Desktop.
Save quangnle/9a03caabd225ab7d3c98 to your computer and use it in GitHub Desktop.
Expression generator selective brackets updated
let rnd = System.Random()
[<AbstractClass>]
type Exp() =
abstract Value:int with get
abstract ExpString:string
default this.Value = 0
default this.ExpString = this.Value.ToString()
type ValueExp (value:int) =
inherit Exp()
override this.Value = value
override this.ExpString = value.ToString()
type BinExp(value:int, left:Exp, op:char, right:Exp, hasBrkt:bool) =
inherit Exp()
override this.Value = value
member this.Left = left
member this.Right = right
member this.Op = op
override this.ExpString =
if hasBrkt then
"(" + left.ExpString + op.ToString() + right.ExpString + ")"
else
left.ExpString + op.ToString() + right.ExpString
let rec getDivisor n =
let d = rnd.Next(1, n)
if n % d = 0 then d
else getDivisor n
let rec add n = rnd.Next(n) |> fun r -> (n - r, r)
let rec sub n = rnd.Next(n) |> fun r -> (n + r, r)
let rec mul n =
match n with
| 0 -> (0, rnd.Next(10))
| _ -> getDivisor(n) |> fun d -> (n / d, d)
let rec div n = rnd.Next(5) |> fun r -> (n * r, r)
let ops = [(add, '+'); (sub, '-'); (mul, '*'); (div, '/')]
let rec getOpPriority op idx =
if idx >= ops.Length then -1
else
let (f, o) = ops.[idx]
if o = op then idx / 2
else getOpPriority op (idx + 1)
let priority op = getOpPriority op 0
let rec gen (value, depth, prevOp) : Exp =
match depth with
| 0 -> upcast new ValueExp(value)
| _ -> let (f, op) = ops.[rnd.Next(3)]
let (l, r) = f(value)
upcast new BinExp(value, gen(l, depth - 1, op), op, gen(r, depth - 1, op), priority prevOp > priority op)
let genExp value depth = gen (value, depth, ' ')
genExp 20 3 |> fun st -> printfn "%s" st.ExpString
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment