Решение на Трета задача от Йордан Петров

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

Към профила на Йордан Петров

Резултати

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

Код

class Expr
def self.build(tree)
case tree.first
when :+ then Addition.new tree[1], tree[2]
when :* then Multiplication.new tree[1], tree[2]
when :number then Number.new tree[1]
when :variable then Variable.new tree[1]
when :- then Negation.new tree[1]
when :sin then Sine.new tree[1]
when :cos then Cosine.new tree[1]
end
end
def -
Negation.new self
end
end
class Unary < Expr
def ==(other)
self.class == other.class && self.value == other.value
end
end
class Binary < Expr
def ==(other)
self.class == other.class &&
self.first == other.first &&
self.second == other.second
end
def +(other)
self.evaluate + other.evaluate
end
def *(other)
self.evaluate * other.evaluate
end
def value
self
end
end
class Number < Unary
attr_reader :value
def initialize(value)
@value = value
end
def evaluate(environment = {})
@value
end
def derive(variable)
Number.new 0
end
def simplify
Number.new @value
end
end
class Addition < Binary
attr_reader :first, :second
def initialize(first, second)
if first.is_a? Expr
@first = first
@second = second
else
@first = Expr.build first
@second = Expr.build second
end
end
def evaluate(environment = {})
@first.evaluate(environment) + @second.evaluate(environment)
end
def derive(variable)
Addition.new(@first.derive(variable), @second.derive(variable)).simplify
end
def simplify
first_simplified = @first.simplify
second_simplified = @second.simplify
if first_simplified.class == Number && second_simplified.class == Number
Number.new (first_simplified.value + second_simplified.value)
elsif first_simplified.value == 0
second_simplified
elsif second_simplified.value == 0
first_simplified
else
Addition.new first_simplified, second_simplified
end
end
end
class Multiplication < Binary
attr_reader :first, :second
def initialize(first, second)
if first.is_a? Expr
@first = first
@second = second
else
@first = Expr.build first
@second = Expr.build second
end
end
def evaluate(environment = {})
@first.evaluate(environment) * @second.evaluate(environment)
end
def derive(variable)
Addition.new(Multiplication.new(@first.derive(variable), @second),
Multiplication.new(@first, second.derive(variable))).simplify
end
def simplify
if @first.simplify.class == Number && @second.simplify.class == Number
Number.new (@first.simplify.value * @second.simplify.value)
elsif @first.simplify.value == 0 || second.simplify.value == 0
Number.new 0
elsif @first.simplify.value == 1
@second.simplify
elsif @second.simplify.value == 1
@first.simplify
else
Multiplication.new @first.simplify, @second.simplify
end
end
end
class Variable < Unary
attr_reader :value
def initialize(value)
@value = value
end
def evaluate(environment = {})
environment[value] || (raise "Variable #{value} does not have value!")
end
def derive(variable)
if @value == variable
Number.new 1
else
Number.new 0
end
end
def simplify
self
end
end
class Negation < Unary
attr_reader :value
def initialize(value)
if value.is_a? Expr
@value = value
else
@value = Expr.build value
end
end
def evaluate(environment = {})
-@value.evaluate(environment)
end
def derive(variable)
Negation.new(@value.derive(variable)).simplify
end
def simplify
simplified_value = @value.simplify
if simplified_value.class == Negation
simplified_value.value
else
Negation.new simplified_value
end
end
end
class Sine < Unary
attr_reader :value
def initialize(value)
if value.is_a? Expr
@value = value
else
@value = Expr.build value
end
end
def evaluate(environment = {})
Math.sin @value.evaluate(environment)
end
def derive(variable)
Multiplication.new(@value.derive(variable), Cosine.new(@value))
end
def simplify
simplified_value = @value
if simplified_value.class == Number
Number.new Math.sin(simplified_value.value)
else
Sine.new simplified_value
end
end
end
class Cosine < Unary
attr_reader :value
def initialize(value)
if value.is_a? Expr
@value = value
else
@value = Expr.build value
end
end
def evaluate(environment = {})
Math.cos @value.evaluate(environment)
end
def derive(variable)
Multiplication.new(@value.derive(variable), -Cosine.new(@value))
end
def simplify
simplified_value = @value.simplify
if simplified_value.class == Number
Number.new Math.cos(simplified_value.value)
else
Cosine.new simplified_value
end
end
end

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

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

Finished in 0.04918 seconds
13 examples, 0 failures

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

Йордан обнови решението на 14.11.2012 13:33 (преди над 11 години)

+class Expr
+ def self.build(tree)
+ case tree.first
+ when :+ then Addition.new tree[1], tree[2]
+ when :* then Multiplication.new tree[1], tree[2]
+ when :number then Number.new tree[1]
+ when :variable then Variable.new tree[1]
+ when :- then Negation.new tree[1]
+ when :sin then Sine.new tree[1]
+ when :cos then Cosine.new tree[1]
+ end
+ end
+
+ def -
+ Negation.new self
+ end
+end
+
+class Unary < Expr
+ def ==(other)
+ self.class == other.class && self.value == other.value
+ end
+end
+
+class Binary < Expr
+ def ==(other)
+ self.class == other.class &&
+ self.first == other.first &&
+ self.second == other.second
+ end
+
+ def +(other)
+ self.evaluate + other.evaluate
+ end
+
+ def *(other)
+ self.evaluate * other.evaluate
+ end
+
+ def value
+ self
+ end
+end
+
+class Number < Unary
+ attr_reader :value
+
+ def initialize(value)
+ @value = value
+ end
+
+ def evaluate(environment = {})
+ @value
+ end
+
+ def derive(variable)
+ Number.new 0
+ end
+
+ def simplify
+ Number.new @value
+ end
+end
+
+class Addition < Binary
+ attr_reader :first, :second
+
+ def initialize(first, second)
+ if first.is_a? Expr
+ @first = first
+ @second = second
+ else
+ @first = Expr.build first
+ @second = Expr.build second
+ end
+ end
+
+ def evaluate(environment = {})
+ @first.evaluate(environment) + @second.evaluate(environment)
+ end
+
+ def derive(variable)
+ Addition.new(@first.derive(variable), @second.derive(variable)).simplify
+ end
+
+ def simplify
+ first_simplified = @first.simplify
+ second_simplified = @second.simplify
+
+ if first_simplified.class == Number && second_simplified.class == Number
+ Number.new (first_simplified.value + second_simplified.value)
+ elsif first_simplified.value == 0
+ second_simplified
+ elsif second_simplified.value == 0
+ first_simplified
+ else
+ Addition.new first_simplified, second_simplified
+ end
+ end
+end
+
+class Multiplication < Binary
+ attr_reader :first, :second
+
+ def initialize(first, second)
+ if first.is_a? Expr
+ @first = first
+ @second = second
+ else
+ @first = Expr.build first
+ @second = Expr.build second
+ end
+ end
+
+ def evaluate(environment = {})
+ @first.evaluate(environment) * @second.evaluate(environment)
+ end
+
+ def derive(variable)
+ Addition.new(Multiplication.new(@first.derive(variable), @second),
+ Multiplication.new(@first, second.derive(variable))).simplify
+ end
+
+ def simplify
+ if @first.simplify.class == Number && @second.simplify.class == Number
+ Number.new (@first.simplify.value * @second.simplify.value)
+ elsif @first.simplify.value == 0 || second.simplify.value == 0
+ Number.new 0
+ elsif @first.simplify.value == 1
+ @second.simplify
+ elsif @second.simplify.value == 1
+ @first.simplify
+ else
+ Multiplication.new @first.simplify, @second.simplify
+ end
+ end
+end
+
+class Variable < Unary
+ attr_reader :value
+
+ def initialize(value)
+ @value = value
+ end
+
+ def evaluate(environment = {})
+ environment[value] || (raise "Variable #{value} does not have value!")
+ end
+
+ def derive(variable)
+ if @value == variable
+ Number.new 1
+ else
+ Number.new 0
+ end
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Negation < Unary
+ attr_reader :value
+
+ def initialize(value)
+ if value.is_a? Expr
+ @value = value
+ else
+ @value = Expr.build value
+ end
+ end
+
+ def evaluate(environment = {})
+ -@value.evaluate(environment)
+ end
+
+ def derive(variable)
+ Negation.new(@value.derive(variable)).simplify
+ end
+
+ def simplify
+ simplified_value = @value.simplify
+ if simplified_value.class == Negation
+ simplified_value.value
+ else
+ Negation.new simplified_value
+ end
+ end
+end
+
+class Sine < Unary
+ attr_reader :value
+
+ def initialize(value)
+ if value.is_a? Expr
+ @value = value
+ else
+ @value = Expr.build value
+ end
+ end
+
+ def evaluate(environment = {})
+ Math.sin @value.evaluate(environment)
+ end
+
+ def derive(variable)
+ Multiplication.new(@value.derive(variable), Cosine.new(@value))
+ end
+
+ def simplify
+ simplified_value = @value
+ if simplified_value.class == Number
+ Number.new Math.sin(simplified_value.value)
+ else
+ Sine.new simplified_value
+ end
+ end
+end
+
+class Cosine < Unary
+ attr_reader :value
+
+ def initialize(value)
+ if value.is_a? Expr
+ @value = value
+ else
+ @value = Expr.build value
+ end
+ end
+
+ def evaluate(environment = {})
+ Math.cos @value.evaluate(environment)
+ end
+
+ def derive(variable)
+ Multiplication.new(@value.derive(variable), -Cosine.new(@value))
+ end
+
+ def simplify
+ simplified_value = @value.simplify
+ if simplified_value.class == Number
+ Number.new Math.cos(simplified_value.value)
+ else
+ Cosine.new simplified_value
+ end
+ end
+end