Решение на Трета задача от Николай Колев

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

Към профила на Николай Колев

Резултати

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

Код

class Expr
def Expr.build(expression)
operator, first, second = expression
case operator
when :sin then Sine.new(Expr.build(first))
when :cos then Cosine.new(Expr.build(first))
when :number then Number.new(first)
when :variable then Variable.new(first)
when :+ then Expr.build(first) + Expr.build(second)
when :* then Expr.build(first) * Expr.build(second)
when :- then -Expr.build(first)
else Number.new(expression)
end
end
def +(other)
Addition.new(self, other)
end
def *(other)
Multiplication.new(self, other)
end
def -@
Negation.new(self)
end
def number?
false
end
end
class Unary < Expr
attr_reader :value
def initialize(value)
@value = value
end
def ==(other)
other.respond_to?(:value) and @value == other.value
end
end
class Binary < Expr
attr_reader :left, :right
def initialize(left, right)
@left, @right = left, right
end
def ==(other)
other.respond_to?(:left) and other.respond_to?(:right) and
@left == other.left and @right == other.right
end
def simplify
left, right = @left.simplify, @right.simplify
if left.number? and right.number?
Number.new(left.value.send(operator, right.value))
else
left.send(operator, right)
end
end
end
class Negation < Unary
def evaluate(context = {})
-(@value.evaluate(context))
end
def derive(variable)
Multiplication.new(-1, @value).derive(variable)
end
def simplify
value = @value.simplify
value.number? ? Number.new(-value) : Negation.new(value)
end
end
class Sine < Unary
def evaluate(context = {})
Math.sin(@value.evaluate(context))
end
def derive(variable)
expr = @value.derive(variable) * Cosine.new(@value)
expr.simplify
end
def simplify
@value.number? ? Number.new(Math.sin(@value.value)) : Sine.new(@value.simplify)
end
end
class Cosine < Unary
def evaluate(context = {})
Math.cos(@value.evaluate(context))
end
def derive(variable)
expr = @value.derive(variable) * -Sine.new(@value)
expr.simplify
end
def simplify
@value.number? ? Number.new(Math.cos(@value.value)) : Cosine.new(@value.simplify)
end
end
class Number < Unary
def evaluate(context = {})
@value
end
def derive(variable)
Number.new(0)
end
def number?
true
end
def simplify
self
end
end
class Variable < Unary
def evaluate(context = {})
context[@value]
end
def derive(variable)
Number.new(@value == variable ? 1 : 0)
end
def simplify
self
end
end
class Addition < Binary
def evaluate(context = {})
@left.evaluate(context) + @right.evaluate(context)
end
def simplify
left, right = @left.simplify, @right.simplify
if left.number? and left.value == 0 then right
elsif right.number? and right.value == 0 then left
else super
end
end
def operator
:+
end
def derive(variable)
expr = @left.derive(variable) + @right.derive(variable)
expr.simplify
end
end
class Multiplication < Binary
def evaluate(context = {})
@left.evaluate(context) * @right.evaluate(context)
end
def simplify
left, right = @left.simplify, @right.simplify
if (left.number? and left.value == 0) or (right.number? and right.value == 0)
Number.new(0)
elsif left.number? and left.value
right
elsif right.number? and right.value
left
else
super
end
end
def operator
:*
end
def derive(variable)
expr = @left.derive(variable) * @right + @left * @right.derive(variable)
expr.simplify
end
end

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

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

Finished in 0.10886 seconds
13 examples, 0 failures

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

Николай обнови решението на 10.11.2012 21:43 (преди около 12 години)

+class Expr
+ def Expr.build(expression)
+ operator, first, second = expression
+ case operator
+ when :sin then Sine.new(Expr.build(first))
+ when :cos then Cosine.new(Expr.build(first))
+ when :number then Number.new(first)
+ when :variable then Variable.new(first)
+ when :+ then Expr.build(first) + Expr.build(second)
+ when :* then Expr.build(first) * Expr.build(second)
+ when :- then -Expr.build(first)
+ else Number.new(expression)
+ end
+ end
+
+ def +(other)
+ Addition.new(self, other)
+ end
+
+ def *(other)
+ Multiplication.new(self, other)
+ end
+
+ def -@
+ Negation.new(self)
+ end
+
+ def number?
+ false
+ end
+end
+
+class Unary < Expr
+ attr_reader :value
+
+ def initialize(value)
+ @value = value
+ end
+
+ def ==(other)
+ other.respond_to?(:value) and @value == other.value
+ end
+end
+
+class Binary < Expr
+ attr_reader :left, :right
+
+ def initialize(left, right)
+ @left, @right = left, right
+ end
+
+ def ==(other)
+ other.respond_to?(:left) and other.respond_to?(:right) and
+ @left == other.left and @right == other.right
+ end
+
+ def simplify
+ left, right = @left.simplify, @right.simplify
+ if left.number? and right.number?
+ Number.new(left.value.send(operator, right.value))
+ else
+ left.send(operator, right)
+ end
+ end
+end
+
+class Negation < Unary
+ def evaluate(context = {})
+ -(@value.evaluate(context))
+ end
+
+ def derive(variable)
+ Multiplication.new(-1, @value).derive(variable)
+ end
+
+ def simplify
+ value = @value.simplify
+ value.number? ? Number.new(-value) : Negation.new(value)
+ end
+end
+
+class Sine < Unary
+ def evaluate(context = {})
+ Math.sin(@value.evaluate(context))
+ end
+
+ def derive(variable)
+ expr = @value.derive(variable) * Cosine.new(@value)
+ expr.simplify
+ end
+
+ def simplify
+ @value.number? ? Number.new(Math.sin(@value.value)) : Sine.new(@value.simplify)
+ end
+end
+
+class Cosine < Unary
+ def evaluate(context = {})
+ Math.cos(@value.evaluate(context))
+ end
+
+ def derive(variable)
+ expr = @value.derive(variable) * -Sine.new(@value)
+ expr.simplify
+ end
+
+ def simplify
+ @value.number? ? Number.new(Math.cos(@value.value)) : Cosine.new(@value.simplify)
+ end
+end
+
+class Number < Unary
+ def evaluate(context = {})
+ @value
+ end
+
+ def derive(variable)
+ Number.new(0)
+ end
+
+ def number?
+ true
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Variable < Unary
+ def evaluate(context = {})
+ context[@value]
+ end
+
+ def derive(variable)
+ Number.new(@value == variable ? 1 : 0)
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Addition < Binary
+ def evaluate(context = {})
+ @left.evaluate(context) + @right.evaluate(context)
+ end
+
+ def simplify
+ left, right = @left.simplify, @right.simplify
+ if left.number? and left.value == 0 then right
+ elsif right.number? and right.value == 0 then left
+ else super
+ end
+ end
+
+ def operator
+ :+
+ end
+
+ def derive(variable)
+ expr = @left.derive(variable) + @right.derive(variable)
+ expr.simplify
+ end
+end
+
+class Multiplication < Binary
+ def evaluate(context = {})
+ @left.evaluate(context) * @right.evaluate(context)
+ end
+
+ def simplify
+ left, right = @left.simplify, @right.simplify
+ if (left.number? and left.value == 0) or (right.number? and right.value == 0)
+ Number.new(0)
+ elsif left.number? and left.value
+ right
+ elsif right.number? and right.value
+ left
+ else
+ super
+ end
+ end
+
+ def operator
+ :*
+ end
+
+ def derive(variable)
+ expr = @left.derive(variable) * @right + @left * @right.derive(variable)
+ expr.simplify
+ end
+end