Денислав обнови решението на 14.11.2012 11:41 (преди около 12 години)
+class Expr
+ def self.build s_expression
+ case s_expression[0]
+ when :number then Number.new s_expression[1]
+ when :variable then Variable.new s_expression[1]
+ when :- then Negation.new self.build(s_expression[1])
+ when :cos then Cosine.new self.build(s_expression[1])
+ when :sin then Sine.new self.build(s_expression[1])
+ when :+ then Addition.new self.build(s_expression[1]), self.build(s_expression[2])
+ when :* then Multiplication.new self.build(s_expression[1]), self.build( s_expression[2])
+ end
+ end
+
+ def + other
+ Addition.new self, other
+ end
+
+ def == other
+ instance_variables.all? do |variable|
+ instance_variable_get(variable) == other.instance_variable_get(variable)
+ end
+ end
+
+ def -@
+ Negation.new self
+ end
+
+ def - other
+ self + (-other)
+ end
+
+ def * other
+ Multiplication.new self, other
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Sine < Expr
+ def initialize expression
+ @expression = expression
+ end
+
+ def evaluate environment = {}
+ Math::sin @expression.evaluate environment
+ end
+
+ def simplify
+ Sine.new @expression.simplify
+ end
+
+ def derive variable
+ Multiplication.new(@expression.derive variable, Cosine.new(expression)).simplify
+ end
+end
+
+class Cosine < Expr
+ def initialize expression
+ @expression = expression
+ end
+
+ def evaluate environment = {}
+ Math::cos @expression.evaluate environment
+ end
+
+ def simplify
+ Cosine.new @expression.simplify
+ end
+
+ def derive variable
+ Multiplication.new(@expression.derive variable, Negation.new(Sine.new(expression))).simplify
+ end
+end
+
+class Negation < Expr
+ def initialize expression
+ @expression = expression
+ end
+
+ def evaluate environment = {}
+ -@expression.evaluate(environment)
+ end
+
+ def simplify
+ Negation.new @expression.simplify
+ end
+
+ def derive variable
+ Negation.new(@expression.derive variable).simplify
+ end
+end
+
+class Multiplication < Expr
+ def initialize multiplier1, multiplier2
+ @multiplier1 = multiplier1
+ @multiplier2 = multiplier2
+ end
+
+ def build s_expression
+ unless s_expression[0] == :*
+ raise "Invalid s-expression to build Multiplication."
+ end
+ Multiplication.new s_expression[1], s_expression[2]
+ end
+
+ def evaluate environment = {}
+ @multiplier1.evaluate(environment) * @multiplier2.evaluate(environment)
+ end
+
+ def simplify
+ if @multiplier1 == Number.new(0) or @multiplier2 == Number.new(0)
+ Number.new 0
+ elsif @multiplier1 == Number.new(1)
+ @multiplier2.simplify
+ elsif @multiplier2 == Number.new(1)
+ @multiplier1.simplify
+ elsif @addend1.class == Number and @addend2.class == Number
+ Number.new evaluate
+ else
+ simpler = Multiplication.new @multiplier1.simplify, @multiplier2.simplify
+ simpler == self ? self : simpler.simplify
+ end
+ end
+
+ def derive variable
+ addend1 = Multiplication.new @multiplier1.derive(variable), @multiplier2
+ addend2 = Multiplication.new @multiplier1, @multiplier2.derive(variable)
+ Addition.new(addend1.simplify, addend2.simplify).simplify
+ end
+end
+
+class Addition < Expr
+ def initialize addend1, addend2
+ @addend1 = addend1
+ @addend2 = addend2
+ end
+
+ def evaluate environment = {}
+ @addend1.evaluate( environment ) + @addend2.evaluate( environment )
+ end
+
+ def simplify
+ if @addend1 == Number.new(0)
+ @addend2.simplify
+ elsif @addend2 == Number.new(0)
+ @addend1.simplify
+ elsif @addend1.class == Number and @addend2.class == Number
+ Number.new evaluate
+ else
+ simpler = Addition.new @addend1.simplify, @addend2.simplify
+ if simpler == self
+ self
+ else
+ simpler.simplify
+ end
+ end
+ end
+
+ def derive variable
+ Addition.new(@addend1.derive(variable), @addend2.derive(variable)).simplify
+ end
+end
+
+class Variable < Expr
+ def initialize symbol
+ @symbol = symbol
+ end
+
+ def evaluate environment = {}
+ substitute @symbol, environment
+ end
+
+ def substitute variable, environment
+ constant = environment[variable]
+ unless constant
+ raise "Invaluable variable ;)"
+ end
+ constant
+ end
+
+ def derive variable
+ if @symbol == variable
+ Number.new 1
+ else
+ Number.new 0
+ end
+ end
+end
+
+class Number < Expr
+ def initialize value
+ @value = value
+ end
+
+ def evaluate environment ={}
+ @value
+ end
+
+ def derive veriable
+ Number.new 0
+ end
+end