Решение на Трета задача от Стоян Найденов

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

Към профила на Стоян Найденов

Резултати

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

Код

class Expr
def Expr.build(input)
case input.first
when :number then Number.new input.drop(1).first
when :variable then Variable.new input.drop(1).first
when :+ then (build(input.drop(1).first) + build(input.last))
when :* then (build(input.drop(1).first) * build(input.last))
when :- then Negation.new build(input.drop(1).first)
when :sin then Sine.new build(input.drop(1).first)
when :cos then Cosine.new build(input.drop(1).first)
end
end
def*(other)
Multiplication.new(self, other)
end
def+(other)
Addition.new(self, other)
end
def-@
Negation.new(self)
end
end
class Unary < Expr
attr_reader :expression
def initialize(expression)
@expression = expression
end
def==(other)
return false if self.class != other.class
self.expression == other.expression
end
def exact?
@expression.exact?
end
end
class Binary < Expr
attr_reader :left_expression, :right_expression
def initialize(left_expression, right_expression)
@left_expression = left_expression
@right_expression = right_expression
end
def==(other)
return false if self.class != other.class
self.left_expression == other.left_expression and
self.right_expression == other.right_expression
end
def exact?
@left_expression.exact? and @right_expression.exact?
end
end
class Addition < Binary
def derive(variable)
(left_expression.derive(variable) + right_expression.derive(variable)).simplify
end
def evaluate(environment = {})
@left_expression.evaluate(environment) + @right_expression.evaluate(environment)
end
def simplify
return Number.new(@left_expression.evaluate + right_expression.evaluate) if exact?
return @right_expression.simplify if @left_expression.simplify == Number.new(0)
return @left_expression.simplify if @right_expression.simplify == Number.new(0)
return @left_expression.simplify + @right_expression.simplify
end
end
class Multiplication < Binary
def derive(variable)
((left_expression.derive(variable) * right_expression) +
(left_expression * right_expression.derive(variable))).simplify
end
def evaluate(environment = {})
@left_expression.evaluate(environment) * @right_expression.evaluate(environment)
end
def simplify
return Number.new(@left_expression.evaluate * right_expression.evaluate) if exact?
return @right_expression.simplify if @left_expression.simplify == Number.new(1)
return @left_expression.simplify if @right_expression.simplify == Number.new(1)
return Number.new(0) if @left_expression.simplify == Number.new(0) or
@right_expression.simplify == Number.new(0)
return @left_expression.simplify * @right_expression.simplify
end
end
class Number < Unary
def derive(variable)
Number.new(0)
end
def evaluate(environment = {})
@expression
end
def simplify
self
end
def exact?
true
end
end
class Variable < Unary
def derive(variable)
@expression == variable ? Number.new(1) : Number.new(0)
end
def evaluate(environment = {})
environment.fetch(@expression)
end
def simplify
self
end
def exact?
false
end
end
class Negation < Unary
def derive(variable)
@expression.derive(variable).simplify
end
def evaluate(environment = {})
-(@expression.evaluate environment)
end
def simplify
-(@expression.evaluate)
end
end
class Sine < Unary
def derive(variable)
(@expression.derive(variable) * (Cosine.new @expression)).simplify
end
def evaluate(environment = {})
Math.sin(@expression.evaluate environment)
end
def simplify
Number.new @expression.evaluate
end
end
class Cosine < Unary
def derive
(@expression.derive(variable) * (-(Sine.new @expression))).simplify
end
def evaluate(environment = {})
Math.cos(@expression.evaluate environment)
end
def simplify
Number.new @expression.evaluate
end
end

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

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

Finished in 0.04967 seconds
13 examples, 0 failures

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

Стоян обнови решението на 14.11.2012 11:24 (преди над 11 години)

+class Expr
+ def Expr.build(input)
+ case input.first
+ when :number then Number.new input.drop(1).first
+ when :variable then Variable.new input.drop(1).first
+ when :+ then (build(input.drop(1).first) + build(input.last))
+ when :* then (build(input.drop(1).first) * build(input.last))
+ when :- then Negation.new build(input.drop(1).first)
+ when :sin then Sine.new build(input.drop(1).first)
+ when :cos then Cosine.new build(input.drop(1).first)
+ end
+ end
+
+ def*(other)
+ Multiplication.new(self, other)
+ end
+
+ def+(other)
+ Addition.new(self, other)
+ end
+
+ def-@
+ Negation.new(self)
+ end
+end
+
+class Unary < Expr
+ attr_reader :expression
+
+ def initialize(expression)
+ @expression = expression
+ end
+
+ def==(other)
+ return false if self.class != other.class
+ self.expression == other.expression
+ end
+
+ def exact?
+ @expression.exact?
+ end
+end
+
+class Binary < Expr
+ attr_reader :left_expression, :right_expression
+
+ def initialize(left_expression, right_expression)
+ @left_expression = left_expression
+ @right_expression = right_expression
+ end
+
+ def==(other)
+ return false if self.class != other.class
+ self.left_expression == other.left_expression and
+ self.right_expression == other.right_expression
+ end
+
+ def exact?
+ @left_expression.exact? and @right_expression.exact?
+ end
+end
+
+class Addition < Binary
+ def derive(variable)
+ (left_expression.derive(variable) + right_expression.derive(variable)).simplify
+ end
+
+ def evaluate(environment = {})
+ @left_expression.evaluate(environment) + @right_expression.evaluate(environment)
+ end
+
+ def simplify
+ return Number.new(@left_expression.evaluate + right_expression.evaluate) if exact?
+ return @right_expression.simplify if @left_expression.simplify == Number.new(0)
+ return @left_expression.simplify if @right_expression.simplify == Number.new(0)
+ return @left_expression.simplify + @right_expression.simplify
+ end
+end
+
+class Multiplication < Binary
+ def derive(variable)
+ ((left_expression.derive(variable) * right_expression) +
+ (left_expression * right_expression.derive(variable))).simplify
+ end
+
+ def evaluate(environment = {})
+ @left_expression.evaluate(environment) * @right_expression.evaluate(environment)
+ end
+
+ def simplify
+ return Number.new(@left_expression.evaluate * right_expression.evaluate) if exact?
+ return @right_expression.simplify if @left_expression.simplify == Number.new(1)
+ return @left_expression.simplify if @right_expression.simplify == Number.new(1)
+ return Number.new(0) if @left_expression.simplify == Number.new(0) or
+ @right_expression.simplify == Number.new(0)
+ return @left_expression.simplify * @right_expression.simplify
+ end
+end
+
+class Number < Unary
+ def derive(variable)
+ Number.new(0)
+ end
+
+ def evaluate(environment = {})
+ @expression
+ end
+
+ def simplify
+ self
+ end
+
+ def exact?
+ true
+ end
+
+end
+
+class Variable < Unary
+ def derive(variable)
+ @expression == variable ? Number.new(1) : Number.new(0)
+ end
+
+ def evaluate(environment = {})
+ environment.fetch(@expression)
+ end
+
+ def simplify
+ self
+ end
+
+ def exact?
+ false
+ end
+end
+
+class Negation < Unary
+ def derive(variable)
+ @expression.derive(variable).simplify
+ end
+
+ def evaluate(environment = {})
+ -(@expression.evaluate environment)
+ end
+
+ def simplify
+ -(@expression.evaluate)
+ end
+end
+
+class Sine < Unary
+ def derive(variable)
+ (@expression.derive(variable) * (Cosine.new @expression)).simplify
+ end
+
+ def evaluate(environment = {})
+ Math.sin(@expression.evaluate environment)
+ end
+
+ def simplify
+ Number.new @expression.evaluate
+ end
+end
+
+class Cosine < Unary
+ def derive
+ (@expression.derive(variable) * (-(Sine.new @expression))).simplify
+ end
+
+ def evaluate(environment = {})
+ Math.cos(@expression.evaluate environment)
+ end
+
+ def simplify
+ Number.new @expression.evaluate
+ end
+end