177 lines
3.7 KiB
Swift
177 lines
3.7 KiB
Swift
indirect enum Expr {
|
|
case Val(Int64)
|
|
case Var(String)
|
|
case Add(Expr, Expr)
|
|
case Mul(Expr, Expr)
|
|
case Pow(Expr, Expr)
|
|
case Ln(Expr)
|
|
}
|
|
|
|
func pown(_ a : Int64, _ n : Int64) -> Int64 {
|
|
if n == 0 {
|
|
return 1
|
|
} else if n == 1 {
|
|
return a
|
|
} else {
|
|
let b = pown(a, n/2)
|
|
if n % 2 == 0 {
|
|
return b*b*a
|
|
} else {
|
|
return b*b
|
|
}
|
|
}
|
|
}
|
|
|
|
func add (_ e1 : Expr, _ e2 : Expr) -> Expr {
|
|
switch (e1, e2) {
|
|
case let (.Val(n), .Val(m)) :
|
|
return .Val(n+m)
|
|
case let (.Val(0), f):
|
|
return f
|
|
case let (f, .Val(0)):
|
|
return f
|
|
case let (f, .Val(n)):
|
|
return add(.Val(n), f)
|
|
case let (.Val(n), .Add(.Val(m), f)):
|
|
return add(.Val(n+m), f)
|
|
case let (f, .Add(.Val(n), g)):
|
|
return add(.Val(n), add(f, g))
|
|
case let (.Add(f, g), h):
|
|
return add(f, add(g, h))
|
|
default:
|
|
return .Add(e1, e2)
|
|
}
|
|
}
|
|
|
|
func mul (_ e1 : Expr, _ e2 : Expr) -> Expr {
|
|
switch (e1, e2) {
|
|
case let (.Val(n), .Val(m)):
|
|
return .Val(n*m)
|
|
case (.Val(0), _):
|
|
return .Val(0)
|
|
case (_, .Val(0)):
|
|
return .Val(0)
|
|
case let (.Val(1), f):
|
|
return f
|
|
case let (f, .Val(1)):
|
|
return f
|
|
case let (f, .Val(n)):
|
|
return mul(.Val(n), f)
|
|
case let (.Val(n), .Mul(.Val(m), f)):
|
|
return mul(.Val(n*m), f)
|
|
case let (f, .Mul(.Val(n), g)):
|
|
return mul(.Val(n), mul(f, g))
|
|
case let (.Mul(f, g), h):
|
|
return mul(f, mul(g, h))
|
|
default:
|
|
return .Mul(e1, e2)
|
|
}
|
|
}
|
|
|
|
func pow (_ e1 : Expr, _ e2 : Expr) -> Expr {
|
|
switch (e1, e2) {
|
|
case let (.Val(m), .Val(n)):
|
|
return .Val(pown(m, n))
|
|
case (_, .Val(0)):
|
|
return .Val(1)
|
|
case let (f, .Val(1)):
|
|
return f
|
|
case (.Val(0), _):
|
|
return .Val(0)
|
|
default:
|
|
return .Pow(e1, e2)
|
|
}
|
|
}
|
|
|
|
func ln (_ e : Expr) -> Expr {
|
|
switch e {
|
|
case .Val(1):
|
|
return .Val(0)
|
|
default:
|
|
return .Ln(e)
|
|
}
|
|
}
|
|
|
|
func d (_ x : String, _ e : Expr) -> Expr {
|
|
switch e {
|
|
case .Val(_):
|
|
return .Val(0)
|
|
case let .Var(y):
|
|
if x == y {
|
|
return .Val(1)
|
|
} else {
|
|
return .Val(0)
|
|
}
|
|
case let .Add(f, g):
|
|
return add(d(x, f), d(x, g))
|
|
case let .Mul(f, g):
|
|
return add(mul(f, d(x, g)), mul(g, d(x, f)))
|
|
case let .Pow(f, g):
|
|
return mul(pow(f, g), add(mul(mul(g, d(x, f)), pow(f, .Val(-1))), mul(ln(f), d(x, g))))
|
|
case let .Ln(f):
|
|
return mul(d(x, f), pow(f, .Val(-1)))
|
|
}
|
|
}
|
|
|
|
func toString (_ e : Expr) -> String {
|
|
switch e {
|
|
case let .Val(n):
|
|
return String(n)
|
|
case let .Var(x):
|
|
return x
|
|
case let .Add(f, g):
|
|
return "(" + toString(f) + " + " + toString(g) + ")"
|
|
case let .Mul(f, g):
|
|
return "(" + toString(f) + " * " + toString(g) + ")"
|
|
case let .Pow(f, g):
|
|
return "(" + toString(f) + " ^ " + toString(g) + ")"
|
|
case let .Ln(f):
|
|
return "ln(" + toString(f) + ")"
|
|
}
|
|
}
|
|
|
|
func count (_ e : Expr) -> UInt32 {
|
|
switch e {
|
|
case .Val(_):
|
|
return 1
|
|
case .Var(_):
|
|
return 1
|
|
case let .Add(f, g):
|
|
return count(f) + count(g)
|
|
case let .Mul(f, g):
|
|
return count(f) + count(g)
|
|
case let .Pow(f, g):
|
|
return count(f) + count(g)
|
|
case let .Ln(f):
|
|
return count(f)
|
|
}
|
|
}
|
|
|
|
func nest_aux (_ s : UInt32, _ f : (_ n : UInt32, _ e : Expr) -> Expr, _ n : UInt32, _ x : Expr) -> Expr {
|
|
if n == 0 {
|
|
return x
|
|
} else {
|
|
let x = f(s - n, x)
|
|
return nest_aux(s, f, n-1, x)
|
|
}
|
|
}
|
|
|
|
func nest (_ f : (_ n : UInt32, _ e : Expr) -> Expr, _ n : UInt32, _ e : Expr) -> Expr {
|
|
return nest_aux(n, f, n, e)
|
|
}
|
|
|
|
func deriv (_ i : UInt32, _ f : Expr) -> Expr {
|
|
let e = d("x", f)
|
|
print(i+1, " count: ", count(e))
|
|
return e
|
|
}
|
|
|
|
var num: UInt32? = 10
|
|
if CommandLine.arguments.count >= 2 {
|
|
num = UInt32(CommandLine.arguments[1])
|
|
}
|
|
|
|
let x = Expr.Var("x")
|
|
let f = pow(x, x)
|
|
let e = nest(deriv, num!, f)
|