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

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

Към профила на Мартин Попов

Резултати

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

Код

module Expr
def self.build(tree)
if tree.count == 2 then Unary.build tree[0], tree[1]
else Binary.build tree[0], tree[1], tree[2]
end
end
end
class Unary
include Math
def self.build(operation, operand)
case operation
when :sin then Sine.new(Expr.build operand)
when :cos then Cosine.new(Expr.build operand)
when :number then Number.new(operand)
when :variable then Variable.new(operand)
when :- then Negation.new(Expr.build operand)
end
end
def ==(other)
if self.class != other.class then false
elsif self.operand != other.operand then false
else true
end
end
def !=(other)
not (self == other)
end
def exact?
operand.exact?
end
end
class Number < Unary
attr_reader :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
operand
end
def simplify
self
end
def exact?
true
end
def derive(variable)
Number.new(0)
end
end
class Variable < Unary
attr_reader :operand
def initialize(operand)
@operand = operand
end
def exact?
false
end
def evaluate(environment = {})
if environment.has_key?(operand) then return environment[operand]
end
puts("you have to define #{operand}")
exit
end
def simplify
self
end
def derive(variable)
if variable == operand then Number.new(1)
else Number.new(0)
end
end
end
class Negation < Unary
attr_reader :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
(-1) * operand.evaluate(environment)
end
def derive(variable)
Negation.new(operand.derive(variable)).simplify
end
def simplify
if exact?
return Number.new evaluate
end
if operand == Number.new(0)
Number.new(0)
end
result = Negation.new operand.simplify
if result.exact? then Number.new result.evaluate
elsif self == result then result
else result.simplify
end
end
end
class Sine < Unary
attr_reader :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
sin(operand.evaluate environment)
end
def derive(variable)
Multiplication.new(operand.derive(variable), Cosine.new(operand)).simplify
end
def simplify
if exact?
return Number.new evaluate
end
result = Sine.new operand.simplify
if result.exact? then Number.new result.evaluate
elsif self == result then result
else result.simplify
end
end
end
class Cosine < Unary
attr_reader :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
cos(operand.evaluate environment)
end
def derive(variable)
Multiplication.new(operand.derive(variable), Negation.new(Sine.new operand)).simplify
end
def simplify
if exact?
Number.new(evaluate)
end
result = Cosine.new operand.simplify
if result.exact? then Number.new result.evaluate
elsif self == result then result
else result.simplify
end
end
end
class Binary
def self.build(operation, left_operand, right_operand)
case operation
when :+ then Addition.new Expr.build(left_operand), Expr.build(right_operand)
when :* then Multiplication.new Expr.build(left_operand), Expr.build(right_operand)
end
end
def exact?
left_operand.exact? and right_operand.exact?
end
def ==(other)
if self.class != other.class then false
elsif self.left_operand != other.left_operand then false
elsif self.right_operand != other.right_operand then false
else true
end
end
def !=(other)
not (self == other)
end
end
class Addition < Binary
attr_reader :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) + right_operand.evaluate(environment)
end
def derive(variable)
Addition.new(left_operand.derive(variable), right_operand.derive(variable)).simplify
end
def simplify
if exact?
Number.new(evaluate)
end
if left_operand == Number.new(0) then return right_operand.simplify
elsif right_operand == Number.new(0) then return left_operand.simplify
end
result = Addition.new left_operand.simplify, right_operand.simplify
if result.exact? then Number.new result.evaluate
elsif self == result then result
else result.simplify
end
end
end
class Multiplication < Binary
attr_accessor :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) * right_operand.evaluate(environment)
end
def derive(variable)
left_aggend = Multiplication.new(left_operand.derive(variable), right_operand)
right_aggend = Multiplication.new(left_operand, right_operand.derive(variable))
Addition.new(left_aggend, right_aggend).simplify
end
def simplify
if exact?
return Number.new(evaluate)
end
if left_operand == Number.new(0) then return Number.new(0)
elsif right_operand == Number.new(0) then return Number.new(0)
elsif left_operand == Number.new(1) then return right_operand.simplify
elsif right_operand == Number.new(1) then return left_operand.simplify
end
result = Multiplication.new left_operand.simplify, right_operand.simplify
if result.exact? then Number.new result.evaluate
elsif self == result then result
else result.simplify
end
end
end

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

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

Finished in 0.0634 seconds
13 examples, 0 failures

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

Мартин обнови решението на 10.11.2012 19:26 (преди около 12 години)

+class Expr
+
+ def self.build(tree)
+ if tree.count == 2 then Unary.build(tree.fetch(0), tree.fetch(1))
+ else Binary.build(tree.fetch(0), tree.fetch(1), tree.fetch(2))
+ end
+ end
+
+end
+
+class Unary < Expr
+
+ include Math
+
+ def self.build(operation, operand)
+ case operation
+ when :sine then Sine.new(Expr.build operand)
+ when :cosine then Cosine.new(Expr.build operand)
+ when :number then Number.new(operand)
+ when :variable then Variable.new(operand)
+ when :- then Negation.new(Expr.build operand)
+ end
+ end
+
+ def ==(other)
+ if self.class != other.class then false
+ elsif self.operand != other.operand then false
+ else true
+ end
+ end
+
+ def !=(other)
+ not self == other
+ end
+
+ def exact?
+ operand.exact?
+ end
+
+end
+
+class Number < Unary
+
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def evaluate(environment = {})
+ operand
+ end
+
+ def simplify
+ self
+ end
+
+ def exact?
+ true
+ end
+
+ def derive(variable)
+ Number.new(0)
+ end
+
+end
+
+class Variable < Unary
+
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def exact?
+ false
+ end
+
+ def evaluate(environment = {})
+ if environment.has_key?(operand) then return environment[operand]
+ end
+ puts("you have to define #{operand}")
+ exit
+ end
+
+ def simplify
+ self
+ end
+
+ def derive(variable)
+ if variable == operand then Number.new(1)
+ else Number.new(0)
+ end
+ end
+
+end
+
+class Negation < Unary
+
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def evaluate(environment = {})
+ (-1) * operand.evaluate(environment)
+ end
+
+ def derive(variable)
+ Negation.new(operand.derive(variable)).simplify
+ end
+
+ def simplify
+ if operand == Number.new(0)
+ Number.new(0)
+ else
+ Negation.new(operand.simplify)
+ end
+ end
+
+end
+
+class Sine < Unary
+
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def evaluate(environment = {})
+ sin(operand.evaluate(environment))
+ end
+
+ def derive(variable)
+ Multiplication.new(operand.derive(variable), Cosine.new(operand)).simplify
+ end
+
+ def simplify
+ operand.simplify
+ end
+
+end
+
+class Cosine < Unary
+
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def evaluate(environment = {})
+ cos(operand.evaluate(environment))
+ end
+
+ def derive(variable)
+ Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand))).simplify
+ end
+
+ def simplify
+ operand.simplify
+ end
+
+end
+
+class Binary < Expr
+
+ def self.build(operation, left_operand, right_operand)
+ case operation
+ when :+ then Addition.new(Expr.build(left_operand), Expr.build(right_operand))
+ when :* then Multiplication.new(Expr.build(left_operand), Expr.build(right_operand))
+ end
+ end
+
+ def exact?
+ left_operand.exact? and right_operand.exact?
+ end
+
+ def ==(other)
+ if self.class != other.class then false
+ elsif self.left_operand != other.left_operand then false
+ elsif self.right_operand != other.right_operand then false
+ else true
+ end
+ end
+
+ def !=(other)
+ not self == other
+ end
+
+end
+
+class Addition < Binary
+
+ attr_accessor :left_operand, :right_operand
+
+ def initialize(left_operand,right_operand)
+ @left_operand = left_operand
+ @right_operand = right_operand
+ end
+
+ def evaluate(environment = {})
+ left_operand.evaluate(environment) + right_operand.evaluate(environment)
+ end
+
+ def derive(variable)
+ Addition.new(left_operand.derive(variable), right_operand.derive(variable)).simplify
+ end
+
+ def simplify
+ if exact?
+ return Number.new(evaluate)
+ end
+ if left_operand == Number.new(0) then right_operand.simplify
+ elsif right_operand == Number.new(0) then left_operand.simplify
+ else Addition.new(left_operand.simplify, right_operand.simplify)
+ end
+ end
+
+end
+
+class Multiplication < Binary
+
+ attr_accessor :left_operand, :right_operand
+
+ def initialize(left_operand,right_operand)
+ @left_operand = left_operand
+ @right_operand = right_operand
+ end
+
+ def evaluate(environment = {})
+ left_operand.evaluate(environment) * right_operand.evaluate(environment)
+ end
+
+ def derive(variable)
+ left_aggend = Multiplication.new(left_operand.derive(variable), right_operand)
+ right_aggend = Multiplication.new(left_operand, right_operand.derive(variable))
+ Addition.new(left_aggend, right_aggend)
+ end
+
+ def simplify
+ if exact?
+ return Number.new(evaluate)
+ end
+ if left_operand == Number.new(0) then Number.new(0)
+ elsif right_operand == Number.new(0) then Number.new(0)
+ elsif left_operand == Number.new(1) then right_operand.simplify
+ else Multiplication.new(left_operand.simplify, right_operand.simplify)
+ end
+ end
+
+end

Мартин обнови решението на 10.11.2012 19:38 (преди около 12 години)

-class Expr
+module Expr
def self.build(tree)
if tree.count == 2 then Unary.build(tree.fetch(0), tree.fetch(1))
else Binary.build(tree.fetch(0), tree.fetch(1), tree.fetch(2))
end
end
end
-class Unary < Expr
+class Unary
include Math
def self.build(operation, operand)
case operation
when :sine then Sine.new(Expr.build operand)
when :cosine then Cosine.new(Expr.build operand)
when :number then Number.new(operand)
when :variable then Variable.new(operand)
when :- then Negation.new(Expr.build operand)
end
end
def ==(other)
if self.class != other.class then false
elsif self.operand != other.operand then false
else true
end
end
def !=(other)
not self == other
end
def exact?
operand.exact?
end
end
class Number < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
operand
end
def simplify
self
end
def exact?
true
end
def derive(variable)
Number.new(0)
end
end
class Variable < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def exact?
false
end
def evaluate(environment = {})
if environment.has_key?(operand) then return environment[operand]
end
puts("you have to define #{operand}")
exit
end
def simplify
self
end
def derive(variable)
if variable == operand then Number.new(1)
else Number.new(0)
end
end
end
class Negation < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
(-1) * operand.evaluate(environment)
end
def derive(variable)
Negation.new(operand.derive(variable)).simplify
end
def simplify
if operand == Number.new(0)
Number.new(0)
else
Negation.new(operand.simplify)
end
end
end
class Sine < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
sin(operand.evaluate(environment))
end
def derive(variable)
Multiplication.new(operand.derive(variable), Cosine.new(operand)).simplify
end
def simplify
operand.simplify
end
end
class Cosine < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
cos(operand.evaluate(environment))
end
def derive(variable)
Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand))).simplify
end
def simplify
operand.simplify
end
end
-class Binary < Expr
+class Binary
def self.build(operation, left_operand, right_operand)
case operation
when :+ then Addition.new(Expr.build(left_operand), Expr.build(right_operand))
when :* then Multiplication.new(Expr.build(left_operand), Expr.build(right_operand))
end
end
def exact?
left_operand.exact? and right_operand.exact?
end
def ==(other)
if self.class != other.class then false
elsif self.left_operand != other.left_operand then false
elsif self.right_operand != other.right_operand then false
else true
end
end
def !=(other)
not self == other
end
end
class Addition < Binary
attr_accessor :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) + right_operand.evaluate(environment)
end
def derive(variable)
Addition.new(left_operand.derive(variable), right_operand.derive(variable)).simplify
end
def simplify
if exact?
return Number.new(evaluate)
end
if left_operand == Number.new(0) then right_operand.simplify
elsif right_operand == Number.new(0) then left_operand.simplify
else Addition.new(left_operand.simplify, right_operand.simplify)
end
end
end
class Multiplication < Binary
attr_accessor :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) * right_operand.evaluate(environment)
end
def derive(variable)
left_aggend = Multiplication.new(left_operand.derive(variable), right_operand)
right_aggend = Multiplication.new(left_operand, right_operand.derive(variable))
Addition.new(left_aggend, right_aggend)
end
def simplify
if exact?
return Number.new(evaluate)
end
if left_operand == Number.new(0) then Number.new(0)
elsif right_operand == Number.new(0) then Number.new(0)
elsif left_operand == Number.new(1) then right_operand.simplify
else Multiplication.new(left_operand.simplify, right_operand.simplify)
end
end
end

Мартин обнови решението на 11.11.2012 01:27 (преди около 12 години)

module Expr
def self.build(tree)
if tree.count == 2 then Unary.build(tree.fetch(0), tree.fetch(1))
else Binary.build(tree.fetch(0), tree.fetch(1), tree.fetch(2))
end
end
end
class Unary
include Math
def self.build(operation, operand)
case operation
- when :sine then Sine.new(Expr.build operand)
- when :cosine then Cosine.new(Expr.build operand)
+ when :sin then Sine.new(Expr.build operand)
+ when :cos then Cosine.new(Expr.build operand)
when :number then Number.new(operand)
when :variable then Variable.new(operand)
when :- then Negation.new(Expr.build operand)
end
end
def ==(other)
if self.class != other.class then false
elsif self.operand != other.operand then false
else true
end
end
def !=(other)
not self == other
end
def exact?
operand.exact?
end
end
class Number < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
operand
end
def simplify
self
end
def exact?
true
end
def derive(variable)
Number.new(0)
end
end
class Variable < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def exact?
false
end
def evaluate(environment = {})
if environment.has_key?(operand) then return environment[operand]
end
puts("you have to define #{operand}")
exit
end
def simplify
self
end
def derive(variable)
if variable == operand then Number.new(1)
else Number.new(0)
end
end
end
class Negation < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
(-1) * operand.evaluate(environment)
end
def derive(variable)
Negation.new(operand.derive(variable)).simplify
end
def simplify
+ if exact?
+ return Number.new(evaluate)
+ end
if operand == Number.new(0)
Number.new(0)
- else
- Negation.new(operand.simplify)
end
+ result = Negation.new(operand.simplify)
+ if result == self then result
+ else result.simplify
+ end
end
end
class Sine < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
sin(operand.evaluate(environment))
end
def derive(variable)
Multiplication.new(operand.derive(variable), Cosine.new(operand)).simplify
end
def simplify
- operand.simplify
+ if exact?
+ return Number.new(evaluate)
+ end
+ result = Sine.new(operand.simplify)
+ if result == self then result
+ else result.simplify
+ end
end
end
class Cosine < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
cos(operand.evaluate(environment))
end
def derive(variable)
Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand))).simplify
end
def simplify
- operand.simplify
+ if exact?
+ Number.new(evaluate)
+ end
+ result = Cosine.new(operand.simplify)
+ if result == self then result
+ else result.simplify
+ end
end
end
class Binary
def self.build(operation, left_operand, right_operand)
case operation
when :+ then Addition.new(Expr.build(left_operand), Expr.build(right_operand))
when :* then Multiplication.new(Expr.build(left_operand), Expr.build(right_operand))
end
end
def exact?
left_operand.exact? and right_operand.exact?
end
def ==(other)
if self.class != other.class then false
elsif self.left_operand != other.left_operand then false
elsif self.right_operand != other.right_operand then false
else true
end
end
def !=(other)
not self == other
end
end
class Addition < Binary
attr_accessor :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) + right_operand.evaluate(environment)
end
def derive(variable)
Addition.new(left_operand.derive(variable), right_operand.derive(variable)).simplify
end
def simplify
if exact?
- return Number.new(evaluate)
+ Number.new(evaluate)
end
- if left_operand == Number.new(0) then right_operand.simplify
- elsif right_operand == Number.new(0) then left_operand.simplify
- else Addition.new(left_operand.simplify, right_operand.simplify)
+ if left_operand == Number.new(0) then return right_operand.simplify
+ elsif right_operand == Number.new(0) then return left_operand.simplify
end
+ result = Addition.new(left_operand.simplify, right_operand.simplify)
+ if self == result then result
+ else result.simplify
+ end
end
end
class Multiplication < Binary
attr_accessor :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) * right_operand.evaluate(environment)
end
def derive(variable)
left_aggend = Multiplication.new(left_operand.derive(variable), right_operand)
right_aggend = Multiplication.new(left_operand, right_operand.derive(variable))
- Addition.new(left_aggend, right_aggend)
+ Addition.new(left_aggend, right_aggend).simplify
end
def simplify
if exact?
return Number.new(evaluate)
end
- if left_operand == Number.new(0) then Number.new(0)
- elsif right_operand == Number.new(0) then Number.new(0)
- elsif left_operand == Number.new(1) then right_operand.simplify
- else Multiplication.new(left_operand.simplify, right_operand.simplify)
+ if left_operand == Number.new(0) then return Number.new(0)
+ elsif right_operand == Number.new(0) then return Number.new(0)
+ elsif left_operand == Number.new(1) then return right_operand.simplify
+ end
+ result = Multiplication.new(left_operand.simplify, right_operand.simplify)
+ if (self == result) then result
+ else result.simplify
end
end
end

Мартин обнови решението на 12.11.2012 17:22 (преди около 12 години)

module Expr
def self.build(tree)
if tree.count == 2 then Unary.build(tree.fetch(0), tree.fetch(1))
else Binary.build(tree.fetch(0), tree.fetch(1), tree.fetch(2))
end
end
end
class Unary
include Math
def self.build(operation, operand)
case operation
when :sin then Sine.new(Expr.build operand)
when :cos then Cosine.new(Expr.build operand)
when :number then Number.new(operand)
when :variable then Variable.new(operand)
when :- then Negation.new(Expr.build operand)
end
end
def ==(other)
if self.class != other.class then false
elsif self.operand != other.operand then false
else true
end
end
def !=(other)
not self == other
end
def exact?
operand.exact?
end
end
class Number < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
operand
end
def simplify
self
end
def exact?
true
end
def derive(variable)
Number.new(0)
end
end
class Variable < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def exact?
false
end
def evaluate(environment = {})
if environment.has_key?(operand) then return environment[operand]
end
puts("you have to define #{operand}")
exit
end
def simplify
self
end
def derive(variable)
if variable == operand then Number.new(1)
else Number.new(0)
end
end
end
class Negation < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
(-1) * operand.evaluate(environment)
end
def derive(variable)
Negation.new(operand.derive(variable)).simplify
end
def simplify
if exact?
return Number.new(evaluate)
end
if operand == Number.new(0)
Number.new(0)
end
result = Negation.new(operand.simplify)
if result == self then result
else result.simplify
end
end
end
class Sine < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
sin(operand.evaluate(environment))
end
def derive(variable)
Multiplication.new(operand.derive(variable), Cosine.new(operand)).simplify
end
def simplify
if exact?
return Number.new(evaluate)
end
result = Sine.new(operand.simplify)
if result == self then result
else result.simplify
end
end
end
class Cosine < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
cos(operand.evaluate(environment))
end
def derive(variable)
Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand))).simplify
end
def simplify
if exact?
Number.new(evaluate)
end
result = Cosine.new(operand.simplify)
if result == self then result
else result.simplify
end
end
end
class Binary
def self.build(operation, left_operand, right_operand)
case operation
when :+ then Addition.new(Expr.build(left_operand), Expr.build(right_operand))
when :* then Multiplication.new(Expr.build(left_operand), Expr.build(right_operand))
end
end
def exact?
left_operand.exact? and right_operand.exact?
end
def ==(other)
if self.class != other.class then false
elsif self.left_operand != other.left_operand then false
elsif self.right_operand != other.right_operand then false
else true
end
end
def !=(other)
not self == other
end
end
class Addition < Binary
attr_accessor :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) + right_operand.evaluate(environment)
end
def derive(variable)
Addition.new(left_operand.derive(variable), right_operand.derive(variable)).simplify
end
def simplify
if exact?
Number.new(evaluate)
end
if left_operand == Number.new(0) then return right_operand.simplify
elsif right_operand == Number.new(0) then return left_operand.simplify
end
result = Addition.new(left_operand.simplify, right_operand.simplify)
- if self == result then result
+ if result.exact? then Number.new(result.evaluate)
+ elsif self == result then result
else result.simplify
end
end
end
class Multiplication < Binary
attr_accessor :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) * right_operand.evaluate(environment)
end
def derive(variable)
left_aggend = Multiplication.new(left_operand.derive(variable), right_operand)
right_aggend = Multiplication.new(left_operand, right_operand.derive(variable))
Addition.new(left_aggend, right_aggend).simplify
end
def simplify
if exact?
return Number.new(evaluate)
end
if left_operand == Number.new(0) then return Number.new(0)
elsif right_operand == Number.new(0) then return Number.new(0)
elsif left_operand == Number.new(1) then return right_operand.simplify
+ elsif right_operand == Number.new(1) then return left_operand.simplify
end
result = Multiplication.new(left_operand.simplify, right_operand.simplify)
- if (self == result) then result
+ if result.exact? then Number.new(result.evaluate)
+ elsif self == result then result
else result.simplify
end
end
end

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

module Expr
-
def self.build(tree)
- if tree.count == 2 then Unary.build(tree.fetch(0), tree.fetch(1))
- else Binary.build(tree.fetch(0), tree.fetch(1), tree.fetch(2))
+ if tree.count == 2 then Unary.build tree[0], tree[1]
+ else Binary.build tree[0], tree[1], tree[2]
end
end
-
end
class Unary
-
include Math
def self.build(operation, operand)
case operation
when :sin then Sine.new(Expr.build operand)
when :cos then Cosine.new(Expr.build operand)
when :number then Number.new(operand)
when :variable then Variable.new(operand)
when :- then Negation.new(Expr.build operand)
end
end
def ==(other)
if self.class != other.class then false
elsif self.operand != other.operand then false
else true
end
end
def !=(other)
- not self == other
+ not (self == other)
end
def exact?
operand.exact?
end
-
end
class Number < Unary
+ attr_reader :operand
- attr_accessor :operand
-
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
operand
end
def simplify
self
end
def exact?
true
end
def derive(variable)
Number.new(0)
end
-
end
class Variable < Unary
+ attr_reader :operand
- attr_accessor :operand
-
def initialize(operand)
@operand = operand
end
def exact?
false
end
def evaluate(environment = {})
if environment.has_key?(operand) then return environment[operand]
end
puts("you have to define #{operand}")
exit
end
def simplify
self
end
def derive(variable)
if variable == operand then Number.new(1)
else Number.new(0)
end
end
-
end
class Negation < Unary
+ attr_reader :operand
- attr_accessor :operand
-
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
(-1) * operand.evaluate(environment)
end
def derive(variable)
Negation.new(operand.derive(variable)).simplify
end
def simplify
if exact?
- return Number.new(evaluate)
+ return Number.new evaluate
end
if operand == Number.new(0)
Number.new(0)
end
- result = Negation.new(operand.simplify)
- if result == self then result
+ result = Negation.new operand.simplify
+ if result.exact? then Number.new result.evaluate
+ elsif self == result then result
else result.simplify
end
end
-
end
class Sine < Unary
+ attr_reader :operand
- attr_accessor :operand
-
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
- sin(operand.evaluate(environment))
+ sin(operand.evaluate environment)
end
def derive(variable)
Multiplication.new(operand.derive(variable), Cosine.new(operand)).simplify
end
def simplify
if exact?
- return Number.new(evaluate)
+ return Number.new evaluate
end
- result = Sine.new(operand.simplify)
- if result == self then result
+ result = Sine.new operand.simplify
+ if result.exact? then Number.new result.evaluate
+ elsif self == result then result
else result.simplify
end
end
-
end
class Cosine < Unary
+ attr_reader :operand
- attr_accessor :operand
-
def initialize(operand)
@operand = operand
end
def evaluate(environment = {})
- cos(operand.evaluate(environment))
+ cos(operand.evaluate environment)
end
def derive(variable)
- Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand))).simplify
+ Multiplication.new(operand.derive(variable), Negation.new(Sine.new operand)).simplify
end
def simplify
if exact?
Number.new(evaluate)
end
- result = Cosine.new(operand.simplify)
- if result == self then result
+ result = Cosine.new operand.simplify
+ if result.exact? then Number.new result.evaluate
+ elsif self == result then result
else result.simplify
end
end
-
end
class Binary
-
def self.build(operation, left_operand, right_operand)
case operation
- when :+ then Addition.new(Expr.build(left_operand), Expr.build(right_operand))
- when :* then Multiplication.new(Expr.build(left_operand), Expr.build(right_operand))
+ when :+ then Addition.new Expr.build(left_operand), Expr.build(right_operand)
+ when :* then Multiplication.new Expr.build(left_operand), Expr.build(right_operand)
end
end
def exact?
left_operand.exact? and right_operand.exact?
end
def ==(other)
if self.class != other.class then false
elsif self.left_operand != other.left_operand then false
elsif self.right_operand != other.right_operand then false
else true
end
end
def !=(other)
- not self == other
+ not (self == other)
end
-
end
class Addition < Binary
+ attr_reader :left_operand, :right_operand
- attr_accessor :left_operand, :right_operand
-
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) + right_operand.evaluate(environment)
end
def derive(variable)
Addition.new(left_operand.derive(variable), right_operand.derive(variable)).simplify
end
def simplify
if exact?
Number.new(evaluate)
end
if left_operand == Number.new(0) then return right_operand.simplify
elsif right_operand == Number.new(0) then return left_operand.simplify
end
- result = Addition.new(left_operand.simplify, right_operand.simplify)
- if result.exact? then Number.new(result.evaluate)
+ result = Addition.new left_operand.simplify, right_operand.simplify
+ if result.exact? then Number.new result.evaluate
elsif self == result then result
else result.simplify
end
end
-
end
class Multiplication < Binary
-
attr_accessor :left_operand, :right_operand
def initialize(left_operand,right_operand)
@left_operand = left_operand
@right_operand = right_operand
end
def evaluate(environment = {})
left_operand.evaluate(environment) * right_operand.evaluate(environment)
end
def derive(variable)
left_aggend = Multiplication.new(left_operand.derive(variable), right_operand)
right_aggend = Multiplication.new(left_operand, right_operand.derive(variable))
Addition.new(left_aggend, right_aggend).simplify
end
def simplify
if exact?
return Number.new(evaluate)
end
if left_operand == Number.new(0) then return Number.new(0)
- elsif right_operand == Number.new(0) then return Number.new(0)
- elsif left_operand == Number.new(1) then return right_operand.simplify
- elsif right_operand == Number.new(1) then return left_operand.simplify
+ elsif right_operand == Number.new(0) then return Number.new(0)
+ elsif left_operand == Number.new(1) then return right_operand.simplify
+ elsif right_operand == Number.new(1) then return left_operand.simplify
end
- result = Multiplication.new(left_operand.simplify, right_operand.simplify)
- if result.exact? then Number.new(result.evaluate)
+ result = Multiplication.new left_operand.simplify, right_operand.simplify
+ if result.exact? then Number.new result.evaluate
elsif self == result then result
else result.simplify
end
end
-
end