Ростислав обнови решението на 14.11.2012 01:40 (преди около 12 години)
+class Expr
+ attr_accessor :tree
+
+ def self.build(tree)
+ @tree = Tree.new(tree)
+ end
+
+ def evaluate(variables)
+ case @tree[0]
+ when :number then @tree[1]
+ when :variable then variables[@tree[1]]
+ when :- then -Expr.build(@tree[1])
+ when :+ then Expr.build(@tree[1]) + Expr.build(@tree[2])
+ when :* then Expr.build(@tree[1]) * Expr.build(@tree[2])
+ end
+ end
+
+ def ==(other)
+ @tree == other.tree
+ end
+end
+
+class Tree
+ attr_accessor :tree
+
+ def initialize(tree)
+ @tree = tree
+ end
+
+ def evaluate(variables)
+ case @tree[0]
+ when :number then @tree[1]
+ when :variable
+ raise 'VariableNotSetException' if variables[@tree[1]] == nil
+ variables[@tree[1]]
+ when :- then -Tree.new(@tree[1]).evaluate(variables)
+ when :+ then Tree.new(@tree[1]).evaluate(variables) + Tree.new(@tree[2]).evaluate(variables)
+ when :* then Tree.new(@tree[1]).evaluate(variables) * Tree.new(@tree[2]).evaluate(variables)
+ when :sin then Math.sin(Tree.new(@tree[1]).evaluate(variables))
+ when :cos then Math.cos(Tree.new(@tree[1]).evaluate(variables))
+ end
+ end
+
+ def ==(other)
+ @tree == other.tree
+ end
+
+ def simplify
+ simplify_array(@tree)
+ @tree = @tree[2] if @tree[0] == :+ && @tree[1][0] == :number && @tree[1][1] == 0
+ @tree = @tree[1] if @tree[0] == :+ && @tree[2][0] == :number && @tree[2][1] == 0
+ @tree = @tree[2] if @tree[0] == :* && @tree[1][0] == :number && @tree[1][1] == 1
+ @tree = @tree[1] if @tree[0] == :* && @tree[2][0] == :number && @tree[2][1] == 1
+ @tree = @tree[1] if @tree[0] == :* && @tree[1][0] == :number && @tree[1][1] == 0
+ @tree = @tree[2] if @tree[0] == :* && @tree[2][0] == :number && @tree[2][1] == 0
+ @tree = @tree[1] if @tree[0] == :sin && @tree[1][1] == 0
+ self
+ end
+
+ def simplify_array(array)
+ @tree.each_with_index do |node, index|
+ @tree[index] = node[2] if node[0] == :+ && node[1][0] == :number && node[1][1] == 0
+ @tree[index] = node[1] if node[0] == :+ && node[2][0] == :number && node[2][1] == 0
+ @tree[index] = node[2] if node[0] == :* && node[1][0] == :number && node[1][1] == 1
+ @tree[index] = node[1] if node[0] == :* && node[2][0] == :number && node[2][1] == 1
+ @tree[index] = node[1] if node[0] == :* && node[1][0] == :number && node[1][1] == 0
+ @tree[index] = node[2] if node[0] == :* && node[2][0] == :number && node[2][1] == 0
+ @tree[index] = node[1] if node[0] == :sin && node[1][1] == 0
+ simplify_array(node[1]) if node[1].class == Array
+ simplify_array(node[2]) if node[2].class == Array
+ end
+ end
+
+ def derive(argument)
+
+ end
+end