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

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

Към профила на Теодор Илиев

Резултати

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

Код

class Expr
def self.build(parse_array)
case parse_array[0]
when :number then Number.new parse_array[1]
when :variable then Variable.new parse_array[1]
when :- then -(build parse_array[1])
when :+ then (build parse_array[1]) + (build parse_array[2])
when :* then (build parse_array[1]) * (build parse_array[2])
when :sin then Sine.new build parse_array[1]
when :cos then Cosine.new build parse_array[1]
end
end
def +(other)
Addition.new self, other
end
def -@
Negation.new self
end
def *(other)
Multiplication.new self, other
end
end
class Unary < Expr
attr_reader :operand
def initialize(operand)
@operand = operand
end
def ==(other)
self.class == other.class and self.operand == other.operand
end
def simplify
self
end
def exact?
@operand.exact?
end
end
class Binary < Expr
attr_reader :left_operand, :right_operand
def initialize(left_operand, right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def ==(other)
self.class == other.class and
self.left_operand == other.left_operand and
self.right_operand == other.right_operand
end
def exact?
@left_operand.exact? and @right_operand.exact?
end
end
class Number < Unary
def evaluate(environment = {})
@operand
end
def derive(variable)
Number.new 0
end
def exact?
true
end
end
class Variable < Unary
def evaluate(environment = {})
fail "Variable #@operand is undefined" unless environment.has_key? @operand
environment[@operand]
end
def derive(variable)
if variable == operand
Number.new 1
else
Number.new 0
end
end
def exact?
false
end
end
class Negation < Unary
def evaluate(environment = {})
-1 * (@operand.evaluate environment)
end
def derive(variable)
(-(@operand.derive(variable))).simplify
end
def simplify
if exact? then return Number.new(-1 * operand.evaluate) end
if operand.simplify.exact? then return Number.new(-1 * operand.simplify.evaluate) end
if operand.simplify.class == Negation then return (operand.simplify).operand end
-(operand.simplify)
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin(@operand.evaluate environment)
end
def derive(variable)
(@operand.derive(variable) * (Cosine.new @operand)).simplify
end
def simplify
if exact? then return Number.new evaluate end
if @operand.simplify.exact? then return Number.new @operand.simplify.evaluate end
Sine.new @operand.simplify
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@operand.evaluate environment)
end
def derive(variable)
(@operand.derive(variable) * -(Sine.new @operand)).simplify
end
def simplify
if exact? then return Number.new evaluate end
if @operand.simplify.exact? then return Number.new @operand.simplify.evaluate end
Cosine.new @operand.simplify
end
end
class Addition < Binary
def evaluate(environment = {})
(@left_operand.evaluate environment) + (@right_operand.evaluate environment)
end
def derive(variable)
(@left_operand.derive(variable) + @right_operand.derive(variable)).simplify
end
def simplify
return Number.new evaluate if exact?
if @left_operand.simplify.exact? and @left_operand.simplify.evaluate == 0
return @right_operand.simplify
end
if @right_operand.simplify.exact? and @right_operand.simplify.evaluate == 0
return @left_operand.simplify
end
@left_operand.simplify + @right_operand.simplify
end
end
class Multiplication < Binary
def evaluate(environment = {})
(@left_operand.evaluate environment) * (@right_operand.evaluate environment)
end
def derive(variable)
(@left_operand.derive(variable) * @right_operand +
@left_operand * @right_operand.derive(variable)).simplify
end
def simplify
return Number.new evaluate if exact?
if @left_operand.simplify.exact?
return Number.new 0 if @left_operand.simplify.evaluate == 0
return @right_operand.simplify if @left_operand.simplify.evaluate == 1
end
if @right_operand.simplify.exact?
return Number.new 0 if @right_operand.simplify.evaluate == 0
return @left_operand.simplify if @right_operand.simplify.evaluate == 1
end
@left_operand.simplify * @right_operand.simplify
end
end

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

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

Finished in 0.04903 seconds
13 examples, 0 failures

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

Теодор обнови решението на 14.11.2012 06:03 (преди около 12 години)

+class Expr
+ def self.build(parse_array)
+ case parse_array[0]
+ when :number then Number.new parse_array[1]
+ when :variable then Variable.new parse_array[1]
+ when :- then -(build parse_array[1])
+ when :+ then (build parse_array[1]) + (build parse_array[2])
+ when :* then (build parse_array[1]) * (build parse_array[2])
+ when :sin then Sine.new build parse_array[1]
+ when :cos then Cosine.new build parse_array[1]
+ end
+ end
+
+ def +(other)
+ Addition.new self, other
+ end
+
+ def -@
+ Negation.new self
+ end
+
+ def *(other)
+ Multiplication.new self, other
+ end
+end
+
+class Unary < Expr
+ attr_reader :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def ==(other)
+ self.class == other.class and self.operand == other.operand
+ end
+
+ def simplify
+ self
+ end
+
+ def exact?
+ @operand.exact?
+ end
+end
+
+class Binary < Expr
+ attr_reader :left_operand, :right_operand
+
+ def initialize(left_operand, right_operand)
+ @left_operand = left_operand
+ @right_operand = right_operand
+ end
+
+ def ==(other)
+ self.class == other.class and
+ self.left_operand == other.left_operand and
+ self.right_operand == other.right_operand
+ end
+
+ def exact?
+ @left_operand.exact? and @right_operand.exact?
+ end
+end
+
+class Number < Unary
+ def evaluate(environment = {})
+ @operand
+ end
+
+ def derive(variable)
+ Number.new 0
+ end
+
+ def exact?
+ true
+ end
+end
+
+class Variable < Unary
+ def evaluate(environment = {})
+ fail "Variable #@operand is undefined" unless environment.has_key? @operand
+ environment[@operand]
+ end
+
+ def derive(variable)
+ if variable == operand
+ Number.new 1
+ else
+ Number.new 0
+ end
+ end
+
+ def exact?
+ false
+ end
+end
+
+class Negation < Unary
+ def evaluate(environment = {})
+ -1 * (@operand.evaluate environment)
+ end
+
+ def derive(variable)
+ (-(@operand.derive(variable))).simplify
+ end
+
+ def simplify
+ if exact? then return Number.new(-1 * operand.evaluate) end
+ if operand.simplify.exact? then return Number.new(-1 * operand.simplify.evaluate) end
+ if operand.simplify.class == Negation then return (operand.simplify).operand end
+ -(operand.simplify)
+ end
+end
+
+class Sine < Unary
+ def evaluate(environment = {})
+ Math.sin(@operand.evaluate environment)
+ end
+
+ def derive(variable)
+ (@operand.derive(variable) * (Cosine.new @operand)).simplify
+ end
+
+ def simplify
+ if exact? then return Number.new evaluate end
+ if @operand.simplify.exact? then return Number.new @operand.simplify.evaluate end
+ Sine.new @operand.simplify
+ end
+end
+
+class Cosine < Unary
+ def evaluate(environment = {})
+ Math.cos(@operand.evaluate environment)
+ end
+
+ def derive(variable)
+ (@operand.derive(variable) * -(Sine.new @operand)).simplify
+ end
+
+ def simplify
+ if exact? then return Number.new evaluate end
+ if @operand.simplify.exact? then return Number.new @operand.simplify.evaluate end
+ Cosine.new @operand.simplify
+ end
+end
+
+class Addition < Binary
+ def evaluate(environment = {})
+ (@left_operand.evaluate environment) + (@right_operand.evaluate environment)
+ end
+
+ def derive(variable)
+ (@left_operand.derive(variable) + @right_operand.derive(variable)).simplify
+ end
+
+ def simplify
+ return Number.new evaluate if exact?
+ if @left_operand.simplify.exact? and @left_operand.simplify.evaluate == 0
+ return @right_operand.simplify
+ end
+ if @right_operand.simplify.exact? and @right_operand.simplify.evaluate == 0
+ return @left_operand.simplify
+ end
+ @left_operand.simplify + @right_operand.simplify
+ end
+end
+
+class Multiplication < Binary
+ def evaluate(environment = {})
+ (@left_operand.evaluate environment) * (@right_operand.evaluate environment)
+ end
+
+ def derive(variable)
+ (@left_operand.derive(variable) * @right_operand +
+ @left_operand * @right_operand.derive(variable)).simplify
+ end
+
+ def simplify
+ return Number.new evaluate if exact?
+ if @left_operand.simplify.exact?
+ return Number.new 0 if @left_operand.simplify.evaluate == 0
+ return @right_operand.simplify if @left_operand.simplify.evaluate == 1
+ end
+ if @right_operand.simplify.exact?
+ return Number.new 0 if @right_operand.simplify.evaluate == 0
+ return @left_operand.simplify if @right_operand.simplify.evaluate == 1
+ end
+ @left_operand.simplify * @right_operand.simplify
+ end
+end