Методи обнови решението на 14.11.2012 16:46 (преди около 12 години)
+class Expr
+ include Math
+ include Enumerable
+ attr_accessor :values
+
+ def initialize(expression)
+ @values = expression
+ case expression.length
+ when 2 then @expression = Unary.new(*expression)
+ when 3 then @expression = Binary.new(*expression)
+ end
+ end
+
+ def interpret(values = {})
+ @expression.interpret(values)
+ end
+
+ def ==(expression)
+ @values == expression.values
+ end
+
+ def +(expression)
+ @expression.value + expression.value
+ end
+
+ def -@()
+ @expression.value * (-1)
+ end
+
+ def *(expression)
+ @expression.value * expression.value
+ end
+
+ def Expr.build(expression)
+ return Expr.new(expression)
+ end
+
+ def evaluate(environment = {})
+ @expression.interpret(environment)
+ end
+
+ def simplify()
+ @expression.simplify
+ end
+
+end
+
+class Unary < Expr
+ attr_reader :expression
+ attr_reader :operation
+ def initialize(operation, operand)
+ case operation
+ when :- then @expression = Negation.new(operand)
+ when :number then @expression = Number.new(operand)
+ when :variable then @expression = Variable.new(operand)
+ when :sin then @expression = Sine.new(operand)
+ when :cos then @expression = Cosine.new(operand)
+ end
+ end
+
+ def interpret(values = {})
+ @expression.interpret(values)
+ end
+
+ def simplify()
+ @expression.simplify
+ end
+end
+
+class Binary < Expr
+ attr_reader :expression
+ attr_reader :left_operand
+ attr_reader :right_operand
+
+ def initialize(operation, left_operand, right_operand)
+ case operation
+ when :+ then @expression = Addition.new(left_operand, right_operand)
+ when :* then @expression = Multiplication.new(left_operand, right_operand)
+ end
+ @left_operand = left_operand
+ @right_operand = right_operand
+ end
+
+ def interpret(values = {})
+ @expression.interpret(values)
+ end
+
+ def simplify()
+ @expression.simplify
+ end
+end
+
+class Number < Unary
+ attr_reader :number
+
+ def initialize(number)
+ @number = number
+ end
+
+ def interpret(values = {})
+ @number
+ end
+
+ def simplify()
+ Expr.new([:number, @number])
+ end
+
+end
+
+class Addition < Binary
+ attr_reader :left_operand
+ attr_reader :right_operand
+
+ def initialize(left_operand, right_operand)
+ @left_operand = Expr.new(left_operand)
+ @right_operand = Expr.new(right_operand)
+ end
+
+ def interpret(values = {})
+ @left_operand.interpret(values) + @right_operand.interpret(values)
+ end
+
+ def simplify()
+ if @left_operand.simplify == 0 and @right_simplify.simplify == 0 then
+ return 0
+ elsif @left_operand.simplify == 0 then
+ return @right_operand.simplify
+ elsif @right_operand.simplify == 0 then
+ return @left_operand.simplify
+ end
+ if @left_operand.simplify.kind_of? Fixnum and @right_operand.simplify.kind_of? Fixnum then
+ return @left_operand.simplify + @right_operand.simplify
+ end
+ self
+ end
+
+end
+
+class Multiplication < Binary
+ attr_reader :left_operand
+ attr_reader :right_operand
+
+ def initialize(left, right)
+ @left_operand = Expr.new(left)
+ @right_operand = Expr.new(right)
+ end
+
+ def interpret(values = {})
+ @left_operand.interpret(values) * @right_operand.interpret(values)
+ end
+
+ def simplify()
+ if @left_operand.simplify == 0 or @right_simplify.simplify == 0 then
+ return Number.new(0)
+ elsif @left_operand.simplify == 1 then
+ return @right_operand.simplify
+ elsif @right_operand.simplify == 1 then
+ return @left_operand.simplify
+ end
+ if @left_operand.simplify.kind_of? Fixnum and @right_operand.simplify.kind_of? Fixnum then
+ return @left_operand.simplify * @right_operand.simplify
+ end
+ self
+ end
+
+end
+
+class Variable < Unary
+ attr_reader :variable
+
+ def initialize(variable)
+ @variable = variable
+ end
+
+ def interpret(values = {})
+ if values[@variable] == nil then
+ raise 'No variable definition'
+ else
+ return values[@variable]
+ end
+ end
+
+ def simplify()
+ self
+ end
+end
+
+class Negation < Unary
+ attr_reader :expression
+
+ def initialize(expression)
+ @expression = Expr.new(expression)
+ end
+
+ def interpret(values = {})
+ (@expression.interpret(values)) * (-1)
+ end
+
+ def simplify()
+ if @expression.simplify.is_a? Fixnum then
+ return @expression.simplify * (-1)
+ else
+ return @expression
+ end
+ end
+
+end
+
+class Sine < Unary
+ include Math
+ attr_reader :expression
+
+ def initialize(expression)
+ @expression = Expr.new(expression)
+ end
+
+ def interpret(values = {})
+ Math.sin(@expression.interpret(values))
+ end
+
+ def simplify()
+ if @expression.simplify.is_a? Fixnum then
+ return Math.sin(@expression.simplify)
+ else
+ return @expression
+ end
+ end
+
+end
+
+class Cosine < Unary
+ include Math
+ attr_reader :expression
+
+ def initialize(expression)
+ @expression = Expr.new(expression)
+ end
+
+ def interpret(values = {})
+ Math.cos(@expression.interpret(values))
+ end
+
+ def simplify()
+ if @expression.simplify.is_a? Fixnum then
+ return Math.cos(@expression.simplify)
+ else
+ return @expression
+ end
+ end
+end
+