Решение на Трета задача от Елена Денева

Обратно към всички решения

Към профила на Елена Денева

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 13 успешни тест(а)
  • 0 неуспешни тест(а)

Код

class Expr
def self.build exprTree
exprTree.length == 2 ? Unary.build(exprTree) : Binary.build(exprTree)
end
def *(other)
Multiplication.new(self,other)
end
def +(other)
Addition.new(self,other)
end
def -@
Negation.new(self)
end
end
class Unary < Expr
def self.build exprTree
case exprTree[0]
when :number then Number.new exprTree[1]
when :variable then Variable.new exprTree[1]
when :- then Negation.build exprTree[1]
when :sin then Sine.build exprTree[1]
when :cos then Cosine.build exprTree[1]
end
end
def == other
self.class == other.class &&
self.expr == other.expr
end
end
class Binary < Expr
def self.build exprTree
case exprTree[0]
when :+ then Addition.build exprTree[1], exprTree[2]
when :* then Multiplication.build exprTree[1], exprTree[2]
end
end
def == other
self.class == other.class &&
self.leftExpr == other.leftExpr &&
self.rightExpr == other.rightExpr
end
end
class Number < Unary
attr_accessor :expr
def initialize expr
@expr = expr
end
def evaluate environment = {}
expr
end
def exact?
true
end
def simplify
Number.new expr
end
def derive x
return Number.new 0
end
end
class Variable < Unary
attr_accessor :expr
def initialize expr
@expr = expr
end
def evaluate environment = {}
environment[expr]
end
def exact?
false
end
def simplify
Variable.new expr
end
def derive y
expr == y ? Number.new(1) : Number.new(0)
end
end
class Negation < Unary
attr_accessor :expr
def initialize expr
@expr = expr
end
def self.build exprTree
self.new Expr.build exprTree
end
def evaluate environment = {}
-expr.evaluate(environment)
end
def exact?
expr.exact?
end
def simplify
simplified = expr.simplify
simplified.exact? ? Number.new(-1 * simplified.evaluate) : -simplified
end
def derive y
(-expr.derive(y)).simplify
end
end
class Sine < Unary
attr_accessor :expr
def initialize expr
@expr = expr
end
def self.build exprTree
self.new Expr.build exprTree
end
def evaluate environment = {}
value = expr.evaluate(environment)
value ? Math.sin(value) : nil
end
def exact?
expr.exact?
end
def simplify
simplified = expr.simplify
simplified.exact? ? Number.new(Math.sin(simplified.evaluate)) : Sine.new(simplified)
end
def derive y
(expr.derive(y) * Cosine.new(expr)).simplify
end
end
class Cosine < Unary
attr_accessor :expr
def initialize expr
@expr = expr
end
def self.build exprTree
self.new(Expr.build(exprTree))
end
def evaluate environment = {}
value = expr.evaluate(environment)
value ? Math.cos(value) : nil
end
def exact?
expr.exact?
end
def simplify
simplified = expr.simplify
simplified.exact? ? Number.new(Math.cos(simplified.evaluate)) : Cosine.new(simplified)
end
def derive y
(expr.derive(y) * -Sine.new(expr)).simplify
end
end
class Addition < Binary
attr_accessor :leftExpr, :rightExpr
def initialize leftExpr, rightExpr
@leftExpr, @rightExpr = leftExpr, rightExpr
end
def self.build leftExprTree, rightExprTree
self.new Expr.build(leftExprTree), Expr.build(rightExprTree)
end
def evaluate(environment = {})
leftValue = leftExpr.evaluate environment
rightValue = rightExpr.evaluate environment
leftValue && rightValue ? leftValue + rightValue : nil
end
def exact?
leftExpr.exact? && rightExpr.exact?
end
def simplify
leftSimplified, rightSimplified = leftExpr.simplify,rightExpr.simplify
return rightSimplified if leftSimplified.exact? && leftSimplified.evaluate == 0
return leftSimplified if rightSimplified.exact? && rightSimplified.evaluate == 0
if leftSimplified.exact? && rightSimplified.exact?
Number.new(leftSimplified.evaluate + rightSimplified.evaluate)
else
leftSimplified + rightSimplified
end
end
def derive y
(leftExpr.derive(y) + rightExpr.derive(y)).simplify
end
end
class Multiplication < Binary
attr_accessor :leftExpr, :rightExpr
def initialize leftExpr, rightExpr
@leftExpr, @rightExpr = leftExpr, rightExpr
end
def self.build leftExprTree, rightExprTree
self.new Expr.build(leftExprTree), Expr.build(rightExprTree)
end
def evaluate environment = {}
leftValue = leftExpr.evaluate(environment)
rightValue = rightExpr.evaluate(environment)
leftValue && rightValue ? leftValue * rightValue : nil
end
def exact?
leftExpr.exact? && rightExpr.exact?
end
def simplify
leftSimplified, rightSimplified = leftExpr.simplify,rightExpr.simplify
if (leftSimplified.exact?)
return rightSimplified if leftSimplified.evaluate == 1
return Number.new 0 if leftSimplified.evaluate == 0
end
if (rightSimplified.exact?)
return leftSimplified if rightSimplified.evaluate == 1
return Number.new 0 if rightSimplified.evaluate == 0
end
if leftSimplified.exact? && rightSimplified.exact?
Number.new(leftSimplified.evaluate * rightSimplified.evaluate)
else
Multiplication.new(leftSimplified,rightSimplified)
end
end
def derive y
(leftExpr.derive(y) * rightExpr + leftExpr * rightExpr.derive(y)).simplify
end
end

Лог от изпълнението

.............

Finished in 0.05566 seconds
13 examples, 0 failures

История (1 версия и 0 коментара)

Елена обнови решението на 10.11.2012 11:23 (преди над 11 години)

+class Expr
+ def self.build exprTree
+ exprTree.length == 2 ? Unary.build(exprTree) : Binary.build(exprTree)
+ end
+
+ def *(other)
+ Multiplication.new(self,other)
+ end
+
+ def +(other)
+ Addition.new(self,other)
+ end
+
+ def -@
+ Negation.new(self)
+ end
+end
+
+class Unary < Expr
+ def self.build exprTree
+ case exprTree[0]
+ when :number then Number.new exprTree[1]
+ when :variable then Variable.new exprTree[1]
+ when :- then Negation.build exprTree[1]
+ when :sin then Sine.build exprTree[1]
+ when :cos then Cosine.build exprTree[1]
+ end
+ end
+
+ def == other
+ self.class == other.class &&
+ self.expr == other.expr
+ end
+end
+
+class Binary < Expr
+ def self.build exprTree
+ case exprTree[0]
+ when :+ then Addition.build exprTree[1], exprTree[2]
+ when :* then Multiplication.build exprTree[1], exprTree[2]
+ end
+ end
+
+ def == other
+ self.class == other.class &&
+ self.leftExpr == other.leftExpr &&
+ self.rightExpr == other.rightExpr
+ end
+end
+
+class Number < Unary
+ attr_accessor :expr
+
+ def initialize expr
+ @expr = expr
+ end
+
+ def evaluate environment = {}
+ expr
+ end
+
+ def exact?
+ true
+ end
+
+ def simplify
+ Number.new expr
+ end
+
+ def derive x
+ return Number.new 0
+ end
+end
+
+class Variable < Unary
+ attr_accessor :expr
+
+ def initialize expr
+ @expr = expr
+ end
+
+ def evaluate environment = {}
+ environment[expr]
+ end
+
+ def exact?
+ false
+ end
+
+ def simplify
+ Variable.new expr
+ end
+
+ def derive y
+ expr == y ? Number.new(1) : Number.new(0)
+ end
+end
+
+class Negation < Unary
+ attr_accessor :expr
+
+ def initialize expr
+ @expr = expr
+ end
+
+ def self.build exprTree
+ self.new Expr.build exprTree
+ end
+
+ def evaluate environment = {}
+ -expr.evaluate(environment)
+ end
+
+ def exact?
+ expr.exact?
+ end
+
+ def simplify
+ simplified = expr.simplify
+ simplified.exact? ? Number.new(-1 * simplified.evaluate) : -simplified
+ end
+
+ def derive y
+ (-expr.derive(y)).simplify
+ end
+end
+
+class Sine < Unary
+ attr_accessor :expr
+
+ def initialize expr
+ @expr = expr
+ end
+
+ def self.build exprTree
+ self.new Expr.build exprTree
+ end
+
+ def evaluate environment = {}
+ value = expr.evaluate(environment)
+ value ? Math.sin(value) : nil
+ end
+
+ def exact?
+ expr.exact?
+ end
+
+ def simplify
+ simplified = expr.simplify
+ simplified.exact? ? Number.new(Math.sin(simplified.evaluate)) : Sine.new(simplified)
+ end
+
+ def derive y
+ (expr.derive(y) * Cosine.new(expr)).simplify
+ end
+end
+
+class Cosine < Unary
+ attr_accessor :expr
+
+ def initialize expr
+ @expr = expr
+ end
+
+ def self.build exprTree
+ self.new(Expr.build(exprTree))
+ end
+
+ def evaluate environment = {}
+ value = expr.evaluate(environment)
+ value ? Math.cos(value) : nil
+ end
+
+ def exact?
+ expr.exact?
+ end
+
+ def simplify
+ simplified = expr.simplify
+ simplified.exact? ? Number.new(Math.cos(simplified.evaluate)) : Cosine.new(simplified)
+ end
+
+ def derive y
+ (expr.derive(y) * -Sine.new(expr)).simplify
+ end
+end
+
+class Addition < Binary
+ attr_accessor :leftExpr, :rightExpr
+
+ def initialize leftExpr, rightExpr
+ @leftExpr, @rightExpr = leftExpr, rightExpr
+ end
+
+ def self.build leftExprTree, rightExprTree
+ self.new Expr.build(leftExprTree), Expr.build(rightExprTree)
+ end
+
+ def evaluate(environment = {})
+ leftValue = leftExpr.evaluate environment
+ rightValue = rightExpr.evaluate environment
+ leftValue && rightValue ? leftValue + rightValue : nil
+ end
+
+ def exact?
+ leftExpr.exact? && rightExpr.exact?
+ end
+
+ def simplify
+ leftSimplified, rightSimplified = leftExpr.simplify,rightExpr.simplify
+ return rightSimplified if leftSimplified.exact? && leftSimplified.evaluate == 0
+ return leftSimplified if rightSimplified.exact? && rightSimplified.evaluate == 0
+ if leftSimplified.exact? && rightSimplified.exact?
+ Number.new(leftSimplified.evaluate + rightSimplified.evaluate)
+ else
+ leftSimplified + rightSimplified
+ end
+ end
+
+ def derive y
+ (leftExpr.derive(y) + rightExpr.derive(y)).simplify
+ end
+end
+
+class Multiplication < Binary
+ attr_accessor :leftExpr, :rightExpr
+
+ def initialize leftExpr, rightExpr
+ @leftExpr, @rightExpr = leftExpr, rightExpr
+ end
+
+ def self.build leftExprTree, rightExprTree
+ self.new Expr.build(leftExprTree), Expr.build(rightExprTree)
+ end
+
+ def evaluate environment = {}
+ leftValue = leftExpr.evaluate(environment)
+ rightValue = rightExpr.evaluate(environment)
+ leftValue && rightValue ? leftValue * rightValue : nil
+ end
+
+ def exact?
+ leftExpr.exact? && rightExpr.exact?
+ end
+
+ def simplify
+ leftSimplified, rightSimplified = leftExpr.simplify,rightExpr.simplify
+ if (leftSimplified.exact?)
+ return rightSimplified if leftSimplified.evaluate == 1
+ return Number.new 0 if leftSimplified.evaluate == 0
+ end
+ if (rightSimplified.exact?)
+ return leftSimplified if rightSimplified.evaluate == 1
+ return Number.new 0 if rightSimplified.evaluate == 0
+ end
+ if leftSimplified.exact? && rightSimplified.exact?
+ Number.new(leftSimplified.evaluate * rightSimplified.evaluate)
+ else
+ Multiplication.new(leftSimplified,rightSimplified)
+ end
+ end
+
+ def derive y
+ (leftExpr.derive(y) * rightExpr + leftExpr * rightExpr.derive(y)).simplify
+ end
+end