Решение на Трета задача от Цвета Гергичанова

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

Към профила на Цвета Гергичанова

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 10 успешни тест(а)
  • 3 неуспешни тест(а)

Код

class Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :+ or tree[0] == :*
@expresion = Binary.new(tree)
else
@expresion = Unary.new(tree)
end
end
def Expr.build(tree)
Expr.new(tree)
end
def ==(expr)
expresion.expresion.arguments == expr.expresion.expresion.arguments
end
def evaluate(environment = {})
expresion.expresion.evaluate(environment)
end
def simplify()
expresion.expresion.simplify()
end
def exact?
if expresion.class == Binary
Expr.new(expresion.expresion.arguments[1]).exact? and
Expr.new(expresion.expresion.arguments[2]).exact?
elsif expresion.class == Unary
if expresion.expresion.class == Variable
false
else
true
end
end
end
def derive(variable)
Expr.new(expresion.expresion.derive(variable)).simplify()
end
end
class Unary < Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :number
@expresion = Number.new(tree)
elsif tree[0] == :variable
@expresion = Variable.new(tree)
elsif tree[0] == :-
@expresion = Negation.new(tree)
elsif tree[0] == :sin
@expresion = Sine.new(tree)
elsif tree[0] == :cos
@expresion = Cosine.new(tree)
end
end
def evaluate(environment = {})
if @expresion.class == Number
expresion.value.evaluate(environment)
elsif @expresion.class == Variable
expresion.variable.evaluate(environment)
elsif @expresion.class == Negation
expresion.argument.evaluate(environment)
elsif @expresion.class == Sine
expresion.argument.evaluate(environment)
elsif @expresion.class == Cosine
expresion.argument.evaluate(environment)
end
end
def simplify()
if @expresion.class == Number
expresion.value.simplify()
elsif @expresion.class == Variable
expresion.variable.simplify()
elsif @expresion.class == Negation
expresion.argument.simplify()
elsif @expresion.class == Sine
expresion.argument.simplify()
elsif @expresion.class == Cosine
expresion.argument.simplify()
end
end
def derive(variable)
if @expresion.class == Number
expresion.value.derive(variable)
elsif @expresion.class == Variable
expresion.variable.derive(variable)
elsif @expresion.class == Negation
expresion.argument.derive(variable)
elsif @expresion.class == Sine
expresion.argument.derive(variable)
elsif @expresion.class == Cosine
expresion.argument.derive(variable)
end
end
end
class Binary < Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :+
@expresion = Addition.new(tree)
else
@expresion = Multiplication.new(tree)
end
end
def evaluate(environment = {})
expresion.arguments.evaluate(environment)
end
def simplify()
expresion.arguments.simplify()
end
def derive(variable)
expresion.arguments.derive(variable)
end
end
class Number < Unary
attr_accessor :value
def initialize (tree)
@value = tree
end
def evaluate(environment = {})
@value[1]
end
def simplify()
@value
end
def derive(variable)
@value = [:number, 0]
end
end
class Addition < Binary
attr_accessor :arguments
def initialize(tree)
@arguments = tree
end
def evaluate(environment = {})
if Expr.new(@arguments).exact?
@arguments[1][1] + @arguments[2][1]
else
Expr.new(@arguments[1]).evaluate(environment) + Expr.new(@arguments[2]).evaluate(environment)
end
end
def simplify ()
if Expr.new(@arguments).exact?
@arguments = [:number, Expr.new(@arguments).evaluate()]
elsif @arguments[1] == [:number, 0]
@arguments = @arguments[2]
elsif @arguments[2] == [:number, 0]
@arguments = @arguments[1]
else
@arguments = [:+, Expr.new(@arguments[1]).simplify(), Expr.new(@arguments[2]).simplify()]
Expr.new(@arguments).simplify()
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@arguments = [:number, 0]
else
@arguments[1] = Expr.new(@arguments[1]).derive(variable)
@arguments[2] = Expr.new(@arguments[2]).derive(variable)
end
end
end
class Multiplication < Binary
attr_accessor :arguments
def initialize(tree)
@arguments = tree
end
def evaluate(environment = {})
if Expr.new(@arguments).exact?
@arguments[1][1] * @arguments[2][1]
else
Expr.new(@arguments[1]).evaluate(environment) * Expr.new(@arguments[2]).evaluate(environment)
end
end
def simplify ()
if Expr.new(@arguments).exact?
@arguments = [:number, Expr.new(@arguments).evaluate()]
elsif @arguments[1] == [:number, 1]
@arguments = @arguments[2]
elsif @arguments[2] == [:number, 1]
@arguments = @arguments[1]
elsif @arguments[1] == [:number, 0] or @arguments[2] == [:number, 0]
@arguments = [:number, 0]
else
@arguments = [:*, Expr.new(@arguments[1]).simplify(), Expr.new(@arguments[2]).simplify()]
Expr.new(@arguments).simplify()
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@arguments = [:number, 0]
else
@arguments = [:+, [:*, Expr.new(@arguments[1]).derive(variable), @arguments[2]],
[:*, @arguments[1], Expr.new(@arguments[2]).derive(variable)]]
end
end
end
class Variable < Unary
attr_accessor :variable
def initialize(tree)
@variable = tree
end
def evaluate(environment = {})
environment[@variable[1]]
end
def simplify()
@variable
end
def derive(variable)
if @variable[1] == variable
@variable = [:number, 1]
else
@variable = [:number, 0]
end
end
end
class Negation < Unary
attr_accessor :value
def initialize(tree)
@value = tree
end
def evaluate(environment = {})
- @value[1]
end
def simplify()
@value
end
def derive(variable)
@value = [:-, Expr.new(@value[1]).derive(variable)]
end
end
class Sine < Unary
attr_accessor :argument
def initialize(tree)
@argument = tree
end
def evaluate(environment = {})
Math.sin(Expr.new(@argument[1]).evaluate(environment))
end
def simplify()
if argument[1] == [:number, 0]
@expresion = [:number, 0]
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@argument = [:number, 0]
else
@argument = [:*, Expr.new(@argument[1]).derive(variable), [:cos, @argument[1]]]
end
end
end
class Cosine < Unary
attr_accessor :argument
def initialize(tree)
@argument = tree
end
def evaluate(environment = {})
Math.cos(Expr.new(@argument[1]).evaluate(environment))
end
def simplify()
@argument
end
def derive(variable)
if Expr.new(@arguments).exact?
@argument = [:number, 0]
else
@argument = [:*, Expr.new(@argument[1]).derive(variable), [:-, [:sin, @argument[1]]]]
end
end
end

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

F.FF.........

Failures:

  1) Expressions assignment supports evaluation
     Failure/Error: build(string).evaluate(env)
     NoMethodError:
       undefined method `-@' for [:number, 2]:Array
     # /tmp/d20130203-23049-ljqgd4/solution.rb:260:in `evaluate'
     # /tmp/d20130203-23049-ljqgd4/solution.rb:21:in `evaluate'
     # /tmp/d20130203-23049-ljqgd4/spec.rb:121:in `evaluate'
     # /tmp/d20130203-23049-ljqgd4/spec.rb:137:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) Expressions assignment supports simplification
     Failure/Error: simplify('x + 0').should eq build('x')
       
       expected: #<Expr:0x96888b0 @expresion=#<Unary:0x9688824 @expresion=#<Variable:0x96887fc @variable=[:variable, :x]>>>
            got: [:variable, :x]
       
       (compared using ==)
       
       Diff:
       @@ -1,5 +1,2 @@
       -#<Expr:0x96888b0
       - @expresion=
       -  #<Unary:0x9688824
       -   @expresion=#<Variable:0x96887fc @variable=[:variable, :x]>>>
       +[:variable, :x]
     # /tmp/d20130203-23049-ljqgd4/spec.rb:146:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) Expressions assignment can derive expressions
     Failure/Error: derive('x').should eq build('1')
       
       expected: #<Expr:0x97984bc @expresion=#<Unary:0x9798494 @expresion=#<Number:0x979846c @value=[:number, 1]>>>
            got: [:number, 1]
       
       (compared using ==)
     # /tmp/d20130203-23049-ljqgd4/spec.rb:161:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.0418 seconds
13 examples, 3 failures

Failed examples:

rspec /tmp/d20130203-23049-ljqgd4/spec.rb:133 # Expressions assignment supports evaluation
rspec /tmp/d20130203-23049-ljqgd4/spec.rb:145 # Expressions assignment supports simplification
rspec /tmp/d20130203-23049-ljqgd4/spec.rb:160 # Expressions assignment can derive expressions

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

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

+class Expr
+ attr_accessor :expresion
+
+ def initialize(tree)
+ if tree[0] == :+ or tree[0] == :*
+ @expresion = Binary.new(tree)
+ else
+ @expresion = Unary.new(tree)
+ end
+ end
+
+ def Expr.build(tree)
+ Expr.new(tree)
+ end
+
+ def ==(expr)
+ expresion.expresion.arguments == expr.expresion.expresion.arguments
+ end
+
+ def evaluate(environment = {})
+ expresion.expresion.evaluate(environment)
+ end
+
+ def simplify()
+ expresion.expresion.simplify()
+ end
+
+ def exact?
+ if expresion.class == Binary
+ Expr.new(expresion.expresion.arguments[1]).exact? and
+ Expr.new(expresion.expresion.arguments[2]).exact?
+ elsif expresion.class == Unary
+ if expresion.expresion.class == Variable
+ false
+ else
+ true
+ end
+ end
+ end
+
+ def derive(variable)
+ Expr.new(expresion.expresion.derive(variable)).simplify()
+ end
+end
+
+class Unary < Expr
+ attr_accessor :expresion
+
+ def initialize(tree)
+ if tree[0] == :number
+ @expresion = Number.new(tree)
+ elsif tree[0] == :variable
+ @expresion = Variable.new(tree)
+ elsif tree[0] == :-
+ @expresion = Negation.new(tree)
+ elsif tree[0] == :sin
+ @expresion = Sine.new(tree)
+ elsif tree[0] == :cos
+ @expresion = Cosine.new(tree)
+ end
+ end
+
+ def evaluate(environment = {})
+ if @expresion.class == Number
+ expresion.value.evaluate(environment)
+ elsif @expresion.class == Variable
+ expresion.variable.evaluate(environment)
+ elsif @expresion.class == Negation
+ expresion.argument.evaluate(environment)
+ elsif @expresion.class == Sine
+ expresion.argument.evaluate(environment)
+ elsif @expresion.class == Cosine
+ expresion.argument.evaluate(environment)
+ end
+ end
+
+ def simplify()
+ if @expresion.class == Number
+ expresion.value.simplify()
+ elsif @expresion.class == Variable
+ expresion.variable.simplify()
+ elsif @expresion.class == Negation
+ expresion.argument.simplify()
+ elsif @expresion.class == Sine
+ expresion.argument.simplify()
+ elsif @expresion.class == Cosine
+ expresion.argument.simplify()
+ end
+ end
+
+ def derive(variable)
+ if @expresion.class == Number
+ expresion.value.derive(variable)
+ elsif @expresion.class == Variable
+ expresion.variable.derive(variable)
+ elsif @expresion.class == Negation
+ expresion.argument.derive(variable)
+ elsif @expresion.class == Sine
+ expresion.argument.derive(variable)
+ elsif @expresion.class == Cosine
+ expresion.argument.derive(variable)
+ end
+ end
+end
+
+class Binary < Expr
+ attr_accessor :expresion
+
+ def initialize(tree)
+ if tree[0] == :+
+ @expresion = Addition.new(tree)
+ else
+ @expresion = Multiplication.new(tree)
+ end
+ end
+
+ def evaluate(environment = {})
+ expresion.arguments.evaluate(environment)
+ end
+
+ def simplify()
+ expresion.arguments.simplify()
+ end
+
+ def derive(variable)
+ expresion.arguments.derive(variable)
+ end
+end
+
+class Number < Unary
+ attr_accessor :value
+
+ def initialize (tree)
+ @value = tree
+ end
+
+ def evaluate(environment = {})
+ @value[1]
+ end
+
+ def simplify()
+ @value
+ end
+
+ def derive(variable)
+ @value = [:number, 0]
+ end
+end
+
+class Addition < Binary
+ attr_accessor :arguments
+
+ def initialize(tree)
+ @arguments = tree
+ end
+
+ def evaluate(environment = {})
+ if Expr.new(@arguments).exact?
+ @arguments[1][1] + @arguments[2][1]
+ else
+ Expr.new(@arguments[1]).evaluate(environment) + Expr.new(@arguments[2]).evaluate(environment)
+ end
+ end
+
+ def simplify ()
+ if Expr.new(@arguments).exact?
+ @arguments = [:number, Expr.new(@arguments).evaluate()]
+ elsif @arguments[1] == [:number, 0]
+ @arguments = @arguments[2]
+ elsif @arguments[2] == [:number, 0]
+ @arguments = @arguments[1]
+ else
+ @arguments = [:+, Expr.new(@arguments[1]).simplify(), Expr.new(@arguments[2]).simplify()]
+ Expr.new(@arguments).simplify()
+ end
+ end
+
+ def derive(variable)
+ if Expr.new(@arguments).exact?
+ @arguments = [:number, 0]
+ else
+ @arguments[1] = Expr.new(@arguments[1]).derive(variable)
+ @arguments[2] = Expr.new(@arguments[2]).derive(variable)
+ end
+ end
+end
+
+class Multiplication < Binary
+ attr_accessor :arguments
+
+ def initialize(tree)
+ @arguments = tree
+ end
+
+ def evaluate(environment = {})
+ if Expr.new(@arguments).exact?
+ @arguments[1][1] * @arguments[2][1]
+ else
+ Expr.new(@arguments[1]).evaluate(environment) * Expr.new(@arguments[2]).evaluate(environment)
+ end
+ end
+
+ def simplify ()
+ if Expr.new(@arguments).exact?
+ @arguments = [:number, Expr.new(@arguments).evaluate()]
+ elsif @arguments[1] == [:number, 1]
+ @arguments = @arguments[2]
+ elsif @arguments[2] == [:number, 1]
+ @arguments = @arguments[1]
+ elsif @arguments[1] == [:number, 0] or @arguments[2] == [:number, 0]
+ @arguments = [:number, 0]
+ else
+ @arguments = [:*, Expr.new(@arguments[1]).simplify(), Expr.new(@arguments[2]).simplify()]
+ Expr.new(@arguments).simplify()
+ end
+ end
+
+ def derive(variable)
+ if Expr.new(@arguments).exact?
+ @arguments = [:number, 0]
+ else
+ @arguments = [:+, [:*, Expr.new(@arguments[1]).derive(variable), @arguments[2]],
+ [:*, @arguments[1], Expr.new(@arguments[2]).derive(variable)]]
+ end
+ end
+end
+
+class Variable < Unary
+ attr_accessor :variable
+
+ def initialize(tree)
+ @variable = tree
+ end
+
+ def evaluate(environment = {})
+ environment[@variable[1]]
+ end
+
+ def simplify()
+ @variable
+ end
+
+ def derive(variable)
+ if @variable[1] == variable
+ @variable = [:number, 1]
+ else
+ @variable = [:number, 0]
+ end
+ end
+end
+
+class Negation < Unary
+ attr_accessor :value
+
+ def initialize(tree)
+ @value = tree
+ end
+
+ def evaluate(environment = {})
+ - @value[1]
+ end
+
+ def simplify()
+ @value
+ end
+
+ def derive(variable)
+ @value = [:-, Expr.new(@value[1]).derive(variable)]
+ end
+end
+
+class Sine < Unary
+ attr_accessor :argument
+
+ def initialize(tree)
+ @argument = tree
+ end
+
+ def evaluate(environment = {})
+ sin(@argument[1])
+ end
+
+ def simplify()
+ if argument[1] == [:number, 0]
+ @expresion = [:number, 0]
+ end
+ end
+
+ def derive(variable)
+ if Expr.new(@arguments).exact?
+ @argument = [:number, 0]
+ else
+ @argument = [:*, Expr.new(@argument[1]).derive(variable), [:cos, @argument[1]]]
+ end
+ end
+end
+
+class Cosine < Unary
+ attr_accessor :argument
+
+ def initialize(tree)
+ @argument = tree
+ end
+
+ def evaluate(environment = {})
+ cos(@argument[1])
+ end
+
+ def simplify()
+ @argument
+ end
+
+ def derive(variable)
+ if Expr.new(@arguments).exact?
+ @argument = [:number, 0]
+ else
+ @argument = [:*, Expr.new(@argument[1]).derive(variable), [:-, [:sin, @argument[1]]]]
+ end
+ end
+end

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

class Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :+ or tree[0] == :*
@expresion = Binary.new(tree)
else
@expresion = Unary.new(tree)
end
end
def Expr.build(tree)
Expr.new(tree)
end
def ==(expr)
expresion.expresion.arguments == expr.expresion.expresion.arguments
end
def evaluate(environment = {})
expresion.expresion.evaluate(environment)
end
def simplify()
expresion.expresion.simplify()
end
def exact?
if expresion.class == Binary
Expr.new(expresion.expresion.arguments[1]).exact? and
Expr.new(expresion.expresion.arguments[2]).exact?
elsif expresion.class == Unary
if expresion.expresion.class == Variable
false
else
true
end
end
end
def derive(variable)
Expr.new(expresion.expresion.derive(variable)).simplify()
end
end
class Unary < Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :number
@expresion = Number.new(tree)
elsif tree[0] == :variable
@expresion = Variable.new(tree)
elsif tree[0] == :-
@expresion = Negation.new(tree)
elsif tree[0] == :sin
@expresion = Sine.new(tree)
elsif tree[0] == :cos
@expresion = Cosine.new(tree)
end
end
def evaluate(environment = {})
if @expresion.class == Number
expresion.value.evaluate(environment)
elsif @expresion.class == Variable
expresion.variable.evaluate(environment)
elsif @expresion.class == Negation
expresion.argument.evaluate(environment)
elsif @expresion.class == Sine
expresion.argument.evaluate(environment)
elsif @expresion.class == Cosine
expresion.argument.evaluate(environment)
end
end
def simplify()
if @expresion.class == Number
expresion.value.simplify()
elsif @expresion.class == Variable
expresion.variable.simplify()
elsif @expresion.class == Negation
expresion.argument.simplify()
elsif @expresion.class == Sine
expresion.argument.simplify()
elsif @expresion.class == Cosine
expresion.argument.simplify()
end
end
def derive(variable)
if @expresion.class == Number
expresion.value.derive(variable)
elsif @expresion.class == Variable
expresion.variable.derive(variable)
elsif @expresion.class == Negation
expresion.argument.derive(variable)
elsif @expresion.class == Sine
expresion.argument.derive(variable)
elsif @expresion.class == Cosine
expresion.argument.derive(variable)
end
end
end
class Binary < Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :+
@expresion = Addition.new(tree)
else
@expresion = Multiplication.new(tree)
end
end
def evaluate(environment = {})
expresion.arguments.evaluate(environment)
end
def simplify()
expresion.arguments.simplify()
end
def derive(variable)
expresion.arguments.derive(variable)
end
end
class Number < Unary
attr_accessor :value
def initialize (tree)
@value = tree
end
def evaluate(environment = {})
@value[1]
end
def simplify()
@value
end
def derive(variable)
@value = [:number, 0]
end
end
class Addition < Binary
attr_accessor :arguments
def initialize(tree)
@arguments = tree
end
def evaluate(environment = {})
if Expr.new(@arguments).exact?
@arguments[1][1] + @arguments[2][1]
else
Expr.new(@arguments[1]).evaluate(environment) + Expr.new(@arguments[2]).evaluate(environment)
end
end
def simplify ()
if Expr.new(@arguments).exact?
@arguments = [:number, Expr.new(@arguments).evaluate()]
elsif @arguments[1] == [:number, 0]
@arguments = @arguments[2]
elsif @arguments[2] == [:number, 0]
@arguments = @arguments[1]
else
@arguments = [:+, Expr.new(@arguments[1]).simplify(), Expr.new(@arguments[2]).simplify()]
Expr.new(@arguments).simplify()
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@arguments = [:number, 0]
else
@arguments[1] = Expr.new(@arguments[1]).derive(variable)
@arguments[2] = Expr.new(@arguments[2]).derive(variable)
end
end
end
class Multiplication < Binary
attr_accessor :arguments
def initialize(tree)
@arguments = tree
end
def evaluate(environment = {})
if Expr.new(@arguments).exact?
@arguments[1][1] * @arguments[2][1]
else
Expr.new(@arguments[1]).evaluate(environment) * Expr.new(@arguments[2]).evaluate(environment)
end
end
def simplify ()
if Expr.new(@arguments).exact?
@arguments = [:number, Expr.new(@arguments).evaluate()]
elsif @arguments[1] == [:number, 1]
@arguments = @arguments[2]
elsif @arguments[2] == [:number, 1]
@arguments = @arguments[1]
elsif @arguments[1] == [:number, 0] or @arguments[2] == [:number, 0]
@arguments = [:number, 0]
else
@arguments = [:*, Expr.new(@arguments[1]).simplify(), Expr.new(@arguments[2]).simplify()]
Expr.new(@arguments).simplify()
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@arguments = [:number, 0]
else
@arguments = [:+, [:*, Expr.new(@arguments[1]).derive(variable), @arguments[2]],
[:*, @arguments[1], Expr.new(@arguments[2]).derive(variable)]]
end
end
end
class Variable < Unary
attr_accessor :variable
def initialize(tree)
@variable = tree
end
def evaluate(environment = {})
environment[@variable[1]]
end
def simplify()
@variable
end
def derive(variable)
if @variable[1] == variable
@variable = [:number, 1]
else
@variable = [:number, 0]
end
end
end
class Negation < Unary
attr_accessor :value
def initialize(tree)
@value = tree
end
def evaluate(environment = {})
- @value[1]
end
def simplify()
@value
end
def derive(variable)
@value = [:-, Expr.new(@value[1]).derive(variable)]
end
end
class Sine < Unary
attr_accessor :argument
def initialize(tree)
@argument = tree
end
def evaluate(environment = {})
- sin(@argument[1])
+ Math.sin(@argument[1])
end
def simplify()
if argument[1] == [:number, 0]
@expresion = [:number, 0]
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@argument = [:number, 0]
else
@argument = [:*, Expr.new(@argument[1]).derive(variable), [:cos, @argument[1]]]
end
end
end
class Cosine < Unary
attr_accessor :argument
def initialize(tree)
@argument = tree
end
def evaluate(environment = {})
- cos(@argument[1])
+ Math.cos(@argument[1])
end
def simplify()
@argument
end
def derive(variable)
if Expr.new(@arguments).exact?
@argument = [:number, 0]
else
@argument = [:*, Expr.new(@argument[1]).derive(variable), [:-, [:sin, @argument[1]]]]
end
end
end

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

class Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :+ or tree[0] == :*
@expresion = Binary.new(tree)
else
@expresion = Unary.new(tree)
end
end
def Expr.build(tree)
Expr.new(tree)
end
def ==(expr)
expresion.expresion.arguments == expr.expresion.expresion.arguments
end
def evaluate(environment = {})
expresion.expresion.evaluate(environment)
end
def simplify()
expresion.expresion.simplify()
end
def exact?
if expresion.class == Binary
Expr.new(expresion.expresion.arguments[1]).exact? and
Expr.new(expresion.expresion.arguments[2]).exact?
elsif expresion.class == Unary
if expresion.expresion.class == Variable
false
else
true
end
end
end
def derive(variable)
Expr.new(expresion.expresion.derive(variable)).simplify()
end
end
class Unary < Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :number
@expresion = Number.new(tree)
elsif tree[0] == :variable
@expresion = Variable.new(tree)
elsif tree[0] == :-
@expresion = Negation.new(tree)
elsif tree[0] == :sin
@expresion = Sine.new(tree)
elsif tree[0] == :cos
@expresion = Cosine.new(tree)
end
end
def evaluate(environment = {})
if @expresion.class == Number
expresion.value.evaluate(environment)
elsif @expresion.class == Variable
expresion.variable.evaluate(environment)
elsif @expresion.class == Negation
expresion.argument.evaluate(environment)
elsif @expresion.class == Sine
expresion.argument.evaluate(environment)
elsif @expresion.class == Cosine
expresion.argument.evaluate(environment)
end
end
def simplify()
if @expresion.class == Number
expresion.value.simplify()
elsif @expresion.class == Variable
expresion.variable.simplify()
elsif @expresion.class == Negation
expresion.argument.simplify()
elsif @expresion.class == Sine
expresion.argument.simplify()
elsif @expresion.class == Cosine
expresion.argument.simplify()
end
end
def derive(variable)
if @expresion.class == Number
expresion.value.derive(variable)
elsif @expresion.class == Variable
expresion.variable.derive(variable)
elsif @expresion.class == Negation
expresion.argument.derive(variable)
elsif @expresion.class == Sine
expresion.argument.derive(variable)
elsif @expresion.class == Cosine
expresion.argument.derive(variable)
end
end
end
class Binary < Expr
attr_accessor :expresion
def initialize(tree)
if tree[0] == :+
@expresion = Addition.new(tree)
else
@expresion = Multiplication.new(tree)
end
end
def evaluate(environment = {})
expresion.arguments.evaluate(environment)
end
def simplify()
expresion.arguments.simplify()
end
def derive(variable)
expresion.arguments.derive(variable)
end
end
class Number < Unary
attr_accessor :value
def initialize (tree)
@value = tree
end
def evaluate(environment = {})
@value[1]
end
def simplify()
@value
end
def derive(variable)
@value = [:number, 0]
end
end
class Addition < Binary
attr_accessor :arguments
def initialize(tree)
@arguments = tree
end
def evaluate(environment = {})
if Expr.new(@arguments).exact?
@arguments[1][1] + @arguments[2][1]
else
Expr.new(@arguments[1]).evaluate(environment) + Expr.new(@arguments[2]).evaluate(environment)
end
end
def simplify ()
if Expr.new(@arguments).exact?
@arguments = [:number, Expr.new(@arguments).evaluate()]
elsif @arguments[1] == [:number, 0]
@arguments = @arguments[2]
elsif @arguments[2] == [:number, 0]
@arguments = @arguments[1]
else
@arguments = [:+, Expr.new(@arguments[1]).simplify(), Expr.new(@arguments[2]).simplify()]
Expr.new(@arguments).simplify()
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@arguments = [:number, 0]
else
@arguments[1] = Expr.new(@arguments[1]).derive(variable)
@arguments[2] = Expr.new(@arguments[2]).derive(variable)
end
end
end
class Multiplication < Binary
attr_accessor :arguments
def initialize(tree)
@arguments = tree
end
def evaluate(environment = {})
if Expr.new(@arguments).exact?
@arguments[1][1] * @arguments[2][1]
else
Expr.new(@arguments[1]).evaluate(environment) * Expr.new(@arguments[2]).evaluate(environment)
end
end
def simplify ()
if Expr.new(@arguments).exact?
@arguments = [:number, Expr.new(@arguments).evaluate()]
elsif @arguments[1] == [:number, 1]
@arguments = @arguments[2]
elsif @arguments[2] == [:number, 1]
@arguments = @arguments[1]
elsif @arguments[1] == [:number, 0] or @arguments[2] == [:number, 0]
@arguments = [:number, 0]
else
@arguments = [:*, Expr.new(@arguments[1]).simplify(), Expr.new(@arguments[2]).simplify()]
Expr.new(@arguments).simplify()
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@arguments = [:number, 0]
else
@arguments = [:+, [:*, Expr.new(@arguments[1]).derive(variable), @arguments[2]],
[:*, @arguments[1], Expr.new(@arguments[2]).derive(variable)]]
end
end
end
class Variable < Unary
attr_accessor :variable
def initialize(tree)
@variable = tree
end
def evaluate(environment = {})
environment[@variable[1]]
end
def simplify()
@variable
end
def derive(variable)
if @variable[1] == variable
@variable = [:number, 1]
else
@variable = [:number, 0]
end
end
end
class Negation < Unary
attr_accessor :value
def initialize(tree)
@value = tree
end
def evaluate(environment = {})
- @value[1]
end
def simplify()
@value
end
def derive(variable)
@value = [:-, Expr.new(@value[1]).derive(variable)]
end
end
class Sine < Unary
attr_accessor :argument
def initialize(tree)
@argument = tree
end
def evaluate(environment = {})
- Math.sin(@argument[1])
+ Math.sin(Expr.new(@argument[1]).evaluate(environment))
end
def simplify()
if argument[1] == [:number, 0]
@expresion = [:number, 0]
end
end
def derive(variable)
if Expr.new(@arguments).exact?
@argument = [:number, 0]
else
@argument = [:*, Expr.new(@argument[1]).derive(variable), [:cos, @argument[1]]]
end
end
end
class Cosine < Unary
attr_accessor :argument
def initialize(tree)
@argument = tree
end
def evaluate(environment = {})
- Math.cos(@argument[1])
+ Math.cos(Expr.new(@argument[1]).evaluate(environment))
end
def simplify()
@argument
end
def derive(variable)
if Expr.new(@arguments).exact?
@argument = [:number, 0]
else
@argument = [:*, Expr.new(@argument[1]).derive(variable), [:-, [:sin, @argument[1]]]]
end
end
end