Решение на Трета задача от Румен Палетов

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

Към профила на Румен Палетов

Резултати

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

Код

class Expr
def Expr.build(ast)
if ast.is_a?(Array) == false then ast
elsif ast[0] == :number then Number.new(ast[1])
elsif ast[0] == :variable then Variable.new(ast[1])
elsif ast[0] == :+ then Addition.new(ast[1], ast[2])
elsif ast[0] == :* then Multiplication.new(ast[1], ast[2])
elsif ast[0] == :- then Negation.new(ast[1])
elsif ast[0] == :sin then Sine.new(ast[1])
elsif ast[0] == :cos then Cosine.new(ast[1])
else nil
end
end
end
class Unary < Expr
attr_reader :value
def initialize(value)
@value = Expr.build(value)
end
def exact?
@value.exact?
end
def ==(other)
@value == other.value
end
end
class Binary < Expr
attr_reader :left, :right
def initialize(left, right)
@left = Expr.build(left)
@right = Expr.build(right)
end
def exact?
@left.exact? and @right.exact?
end
def ==(other)
@left == other.left and @right == other.right
end
end
class Addition < Binary
def evaluate(environment = {})
@left.evaluate(environment) + @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Addition.new(@left.evaluate, @right)
elsif @right.exact? then Addition.new(@left, @right.evaluate)
else Addition.new(@left, @right)
end
end
def derive(variable)
addition = Addition.new(@left.derive(variable), @right.derive(variable))
addition.simplify
end
end
class Multiplication < Binary
def evaluate(environment = {})
@left.evaluate(environment) * @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Multiplication.new(@left.evaluate, @right)
elsif @right.exact? then Multiplication.new(@left, @right.evaluate)
else Multiplication.new(@left, @right)
end
end
def derive(variable)
mult1 = Multiplication.new(@left.derive(variable), @right)
mult2 = Multiplication.new(@left, @right.derive(variable))
addition = Addition.new(mult1, mult2)
addition.simplify
end
end
class Number < Unary
def evaluate(environment = {})
@value
end
def exact?
true
end
def simplify
evaluate
end
def derive(variable)
Number.new(0)
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Sine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Cosine.new(@value)).simplify
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Cosine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Negation.new(Sine.new(@value))).simplify
end
end
class Negation < Unary
def evaluate(environment = {})
-1 * @value.evaluate(environment)
end
def simplify
if exact? then evaluate
else Negation.new(@value)
end
end
def derive(variable)
Negation.new(@value.derive(variable)).simplify
end
end
class Variable < Unary
def evaluate(environment = {})
if environment.key?(@value) then environment[@value]
else @value
end
end
def exact?
false
end
def simplify
Variable.new(@value)
end
def derive(variable)
if @value == variable then Number.new(1)
else Number.new(0)
end
end
end

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

..FF.........

Failures:

  1) Expressions assignment supports simplification
     Failure/Error: simplify('x + 0').should eq build('x')
     NoMethodError:
       undefined method `left' for #<Variable:0xa13b230 @value=:x>
     # /tmp/d20130203-23049-1veb74b/solution.rb:45:in `=='
     # /tmp/d20130203-23049-1veb74b/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)>'

  2) Expressions assignment can derive expressions
     Failure/Error: derive('x + x').should eq build('2')
     NoMethodError:
       undefined method `value' for 2:Fixnum
     # /tmp/d20130203-23049-1veb74b/solution.rb:28:in `=='
     # /tmp/d20130203-23049-1veb74b/spec.rb:164: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.04159 seconds
13 examples, 2 failures

Failed examples:

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

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

Румен обнови решението на 14.11.2012 03:59 (преди над 11 години)

+class Expr
+ def Expr.build(ast)
+ if ast.is_a?(Array) == false then ast
+ elsif ast[0] == :number then Number.new(ast[1])
+ elsif ast[0] == :variable then Variable.new(ast[1])
+ elsif ast[0] == :+ then Addition.new(ast[1], ast[2])
+ elsif ast[0] == :* then Multiplication.new(ast[1], ast[2])
+ elsif ast[0] == :- then Negation.new(ast[1])
+ elsif ast[0] == :sin then Sine.new(ast[1])
+ elsif ast[0] == :cos then Cosine.new(ast[1])
+ else nil
+ end
+ end
+end
+
+class Unary < Expr
+ def initialize(value)
+ @value = Expr.build(value)
+ end
+
+ def exact?
+ @value.exact?
+ end
+
+ def ==(other)
+ @value == other
+ end
+end
+
+class Binary < Expr
+ def initialize(left, right)
+ @left = Expr.build(left)
+ @right = Expr.build(right)
+ end
+
+ def exact?
+ @left.exact? and @right.exact?
+ end
+
+ def ==(other)
+ @left == other.left and @right == other.right
+ end
+end
+
+class Addition < Binary
+ def evaluate(environment = {})
+ @left.evaluate(environment) + @right.evaluate(environment)
+ end
+
+ def simplify
+ if exact? then evaluate
+ elsif @left.exact? then Addition.new(@left.evaluate, @right)
+ elsif @right.exact? then Addition.new(@left, @right.evaluate)
+ else Addition.new(@left, @right)
+ end
+ end
+
+ def derive(variable)
+ addition = Addition.new(@left.derive(variable), @right.derive(variable))
+ addition.simplify
+ end
+end
+
+class Multiplication < Binary
+ def evaluate(environment = {})
+ @left.evaluate(environment) * @right.evaluate(environment)
+ end
+
+ def simplify
+ if exact? then evaluate
+ elsif @left.exact? then Multiplication.new(@left.evaluate, @right)
+ elsif @right.exact? then Multiplication.new(@left, @right.evaluate)
+ else Multiplication.new(@left, @right)
+ end
+ end
+
+ def derive(variable)
+ mult1 = Multiplication.new(@left.derive(variable), @right)
+ mult2 = Multiplication.new(@left, @right.derive(variable))
+ addition = Addition.new(mult1, mult2)
+ addition.simplify
+ end
+end
+
+class Number < Unary
+ def evaluate(environment = {})
+ @value
+ end
+
+ def exact?
+ true
+ end
+
+ def simplify
+ evaluate
+ end
+
+ def derive(variable)
+ Number.new(0)
+ end
+end
+
+class Sine < Unary
+ def evaluate(environment = {})
+ Math.sin(@value.evaluate(environment))
+ end
+
+ def simplify
+ if exact? then evaluate
+ else Sine.new(@value)
+ end
+ end
+
+ def derive(variable)
+ Multiplication.new(@value.derive(variable), Cosine.new(@value)).simplify
+ end
+end
+
+class Cosine < Unary
+ def evaluate(environment = {})
+ Math.cos(@value.evaluate(environment))
+ end
+
+ def simplify
+ if exact? then evaluate
+ else Cosine.new(@value)
+ end
+ end
+
+ def derive(variable)
+ Multiplication.new(@value.derive(variable), Negation.new(Sine.new(@value))).simplify
+ end
+end
+
+class Negation < Unary
+ def evaluate(environment = {})
+ -1 * @value.evaluate(environment)
+ end
+
+ def simplify
+ if exact? then evaluate
+ else Negation.new(@value)
+ end
+ end
+
+ def derive(variable)
+ Negation.new(@value.derive)
+ end
+end
+
+class Variable < Unary
+ def evaluate(environment = {})
+ if environment.key?(@value) then environment[@value]
+ else @value
+ end
+ end
+
+ def exact?
+ false
+ end
+
+ def simplify
+ Variable.new(@value)
+ end
+
+ def derive(variable)
+ if @value == variable then Number.new(1)
+ else Number.new(0)
+ end
+ end
+end

Румен обнови решението на 14.11.2012 04:04 (преди над 11 години)

class Expr
def Expr.build(ast)
if ast.is_a?(Array) == false then ast
- elsif ast[0] == :number then Number.new(ast[1])
- elsif ast[0] == :variable then Variable.new(ast[1])
- elsif ast[0] == :+ then Addition.new(ast[1], ast[2])
- elsif ast[0] == :* then Multiplication.new(ast[1], ast[2])
- elsif ast[0] == :- then Negation.new(ast[1])
- elsif ast[0] == :sin then Sine.new(ast[1])
- elsif ast[0] == :cos then Cosine.new(ast[1])
- else nil
- end
+ elsif ast[0] == :number then Number.new(ast[1])
+ elsif ast[0] == :variable then Variable.new(ast[1])
+ elsif ast[0] == :+ then Addition.new(ast[1], ast[2])
+ elsif ast[0] == :* then Multiplication.new(ast[1], ast[2])
+ elsif ast[0] == :- then Negation.new(ast[1])
+ elsif ast[0] == :sin then Sine.new(ast[1])
+ elsif ast[0] == :cos then Cosine.new(ast[1])
+ else nil
+ end
end
end
class Unary < Expr
def initialize(value)
@value = Expr.build(value)
end
def exact?
@value.exact?
end
def ==(other)
@value == other
end
end
class Binary < Expr
def initialize(left, right)
@left = Expr.build(left)
- @right = Expr.build(right)
+ @right = Expr.build(right)
end
def exact?
@left.exact? and @right.exact?
end
def ==(other)
@left == other.left and @right == other.right
end
end
class Addition < Binary
def evaluate(environment = {})
@left.evaluate(environment) + @right.evaluate(environment)
end
def simplify
if exact? then evaluate
- elsif @left.exact? then Addition.new(@left.evaluate, @right)
- elsif @right.exact? then Addition.new(@left, @right.evaluate)
- else Addition.new(@left, @right)
- end
+ elsif @left.exact? then Addition.new(@left.evaluate, @right)
+ elsif @right.exact? then Addition.new(@left, @right.evaluate)
+ else Addition.new(@left, @right)
+ end
end
def derive(variable)
addition = Addition.new(@left.derive(variable), @right.derive(variable))
- addition.simplify
+ addition.simplify
end
end
class Multiplication < Binary
def evaluate(environment = {})
@left.evaluate(environment) * @right.evaluate(environment)
end
def simplify
if exact? then evaluate
- elsif @left.exact? then Multiplication.new(@left.evaluate, @right)
- elsif @right.exact? then Multiplication.new(@left, @right.evaluate)
- else Multiplication.new(@left, @right)
- end
+ elsif @left.exact? then Multiplication.new(@left.evaluate, @right)
+ elsif @right.exact? then Multiplication.new(@left, @right.evaluate)
+ else Multiplication.new(@left, @right)
+ end
end
def derive(variable)
mult1 = Multiplication.new(@left.derive(variable), @right)
- mult2 = Multiplication.new(@left, @right.derive(variable))
+ mult2 = Multiplication.new(@left, @right.derive(variable))
addition = Addition.new(mult1, mult2)
- addition.simplify
+ addition.simplify
end
end
class Number < Unary
def evaluate(environment = {})
@value
end
def exact?
true
end
def simplify
evaluate
end
def derive(variable)
Number.new(0)
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
- else Sine.new(@value)
- end
+ else Sine.new(@value)
+ end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Cosine.new(@value)).simplify
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
- else Cosine.new(@value)
- end
+ else Cosine.new(@value)
+ end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Negation.new(Sine.new(@value))).simplify
end
end
class Negation < Unary
def evaluate(environment = {})
-1 * @value.evaluate(environment)
end
def simplify
if exact? then evaluate
else Negation.new(@value)
end
end
def derive(variable)
Negation.new(@value.derive)
end
end
class Variable < Unary
def evaluate(environment = {})
if environment.key?(@value) then environment[@value]
else @value
end
end
def exact?
false
end
def simplify
Variable.new(@value)
end
def derive(variable)
if @value == variable then Number.new(1)
else Number.new(0)
end
end
end

Румен обнови решението на 14.11.2012 04:09 (преди над 11 години)

class Expr
def Expr.build(ast)
if ast.is_a?(Array) == false then ast
elsif ast[0] == :number then Number.new(ast[1])
elsif ast[0] == :variable then Variable.new(ast[1])
elsif ast[0] == :+ then Addition.new(ast[1], ast[2])
elsif ast[0] == :* then Multiplication.new(ast[1], ast[2])
elsif ast[0] == :- then Negation.new(ast[1])
elsif ast[0] == :sin then Sine.new(ast[1])
elsif ast[0] == :cos then Cosine.new(ast[1])
else nil
end
end
end
class Unary < Expr
def initialize(value)
@value = Expr.build(value)
end
def exact?
@value.exact?
end
def ==(other)
@value == other
end
end
class Binary < Expr
def initialize(left, right)
@left = Expr.build(left)
@right = Expr.build(right)
end
def exact?
@left.exact? and @right.exact?
end
def ==(other)
@left == other.left and @right == other.right
end
end
class Addition < Binary
def evaluate(environment = {})
@left.evaluate(environment) + @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Addition.new(@left.evaluate, @right)
elsif @right.exact? then Addition.new(@left, @right.evaluate)
else Addition.new(@left, @right)
end
end
def derive(variable)
addition = Addition.new(@left.derive(variable), @right.derive(variable))
addition.simplify
end
end
class Multiplication < Binary
def evaluate(environment = {})
@left.evaluate(environment) * @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Multiplication.new(@left.evaluate, @right)
elsif @right.exact? then Multiplication.new(@left, @right.evaluate)
else Multiplication.new(@left, @right)
end
end
def derive(variable)
mult1 = Multiplication.new(@left.derive(variable), @right)
mult2 = Multiplication.new(@left, @right.derive(variable))
addition = Addition.new(mult1, mult2)
addition.simplify
end
end
class Number < Unary
def evaluate(environment = {})
@value
end
def exact?
true
end
def simplify
evaluate
end
def derive(variable)
Number.new(0)
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Sine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Cosine.new(@value)).simplify
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Cosine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Negation.new(Sine.new(@value))).simplify
end
end
class Negation < Unary
def evaluate(environment = {})
-1 * @value.evaluate(environment)
end
def simplify
if exact? then evaluate
- else Negation.new(@value)
- end
+ else Negation.new(@value)
+ end
end
def derive(variable)
Negation.new(@value.derive)
end
end
class Variable < Unary
def evaluate(environment = {})
if environment.key?(@value) then environment[@value]
- else @value
- end
+ else @value
+ end
end
def exact?
false
end
def simplify
Variable.new(@value)
end
def derive(variable)
if @value == variable then Number.new(1)
- else Number.new(0)
- end
+ else Number.new(0)
+ end
end
end

Румен обнови решението на 14.11.2012 04:14 (преди над 11 години)

class Expr
def Expr.build(ast)
if ast.is_a?(Array) == false then ast
elsif ast[0] == :number then Number.new(ast[1])
elsif ast[0] == :variable then Variable.new(ast[1])
elsif ast[0] == :+ then Addition.new(ast[1], ast[2])
elsif ast[0] == :* then Multiplication.new(ast[1], ast[2])
elsif ast[0] == :- then Negation.new(ast[1])
elsif ast[0] == :sin then Sine.new(ast[1])
elsif ast[0] == :cos then Cosine.new(ast[1])
else nil
end
end
end
class Unary < Expr
def initialize(value)
@value = Expr.build(value)
end
def exact?
@value.exact?
end
def ==(other)
@value == other
end
end
class Binary < Expr
def initialize(left, right)
@left = Expr.build(left)
@right = Expr.build(right)
end
def exact?
@left.exact? and @right.exact?
end
def ==(other)
@left == other.left and @right == other.right
end
end
class Addition < Binary
def evaluate(environment = {})
@left.evaluate(environment) + @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Addition.new(@left.evaluate, @right)
elsif @right.exact? then Addition.new(@left, @right.evaluate)
else Addition.new(@left, @right)
end
end
def derive(variable)
addition = Addition.new(@left.derive(variable), @right.derive(variable))
addition.simplify
end
end
class Multiplication < Binary
def evaluate(environment = {})
@left.evaluate(environment) * @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Multiplication.new(@left.evaluate, @right)
elsif @right.exact? then Multiplication.new(@left, @right.evaluate)
else Multiplication.new(@left, @right)
end
end
def derive(variable)
mult1 = Multiplication.new(@left.derive(variable), @right)
mult2 = Multiplication.new(@left, @right.derive(variable))
addition = Addition.new(mult1, mult2)
addition.simplify
end
end
class Number < Unary
def evaluate(environment = {})
@value
end
def exact?
true
end
def simplify
evaluate
end
def derive(variable)
Number.new(0)
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Sine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Cosine.new(@value)).simplify
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Cosine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Negation.new(Sine.new(@value))).simplify
end
end
class Negation < Unary
def evaluate(environment = {})
-1 * @value.evaluate(environment)
end
def simplify
if exact? then evaluate
else Negation.new(@value)
end
end
def derive(variable)
- Negation.new(@value.derive)
+ Negation.new(@value.derive).simplify
end
end
class Variable < Unary
def evaluate(environment = {})
if environment.key?(@value) then environment[@value]
else @value
end
end
def exact?
false
end
def simplify
Variable.new(@value)
end
def derive(variable)
if @value == variable then Number.new(1)
else Number.new(0)
end
end
end

Румен обнови решението на 14.11.2012 04:15 (преди над 11 години)

class Expr
def Expr.build(ast)
if ast.is_a?(Array) == false then ast
elsif ast[0] == :number then Number.new(ast[1])
elsif ast[0] == :variable then Variable.new(ast[1])
elsif ast[0] == :+ then Addition.new(ast[1], ast[2])
elsif ast[0] == :* then Multiplication.new(ast[1], ast[2])
elsif ast[0] == :- then Negation.new(ast[1])
elsif ast[0] == :sin then Sine.new(ast[1])
elsif ast[0] == :cos then Cosine.new(ast[1])
else nil
end
end
end
class Unary < Expr
def initialize(value)
@value = Expr.build(value)
end
def exact?
@value.exact?
end
def ==(other)
@value == other
end
end
class Binary < Expr
def initialize(left, right)
@left = Expr.build(left)
@right = Expr.build(right)
end
def exact?
@left.exact? and @right.exact?
end
def ==(other)
@left == other.left and @right == other.right
end
end
class Addition < Binary
def evaluate(environment = {})
@left.evaluate(environment) + @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Addition.new(@left.evaluate, @right)
elsif @right.exact? then Addition.new(@left, @right.evaluate)
else Addition.new(@left, @right)
end
end
def derive(variable)
addition = Addition.new(@left.derive(variable), @right.derive(variable))
addition.simplify
end
end
class Multiplication < Binary
def evaluate(environment = {})
@left.evaluate(environment) * @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Multiplication.new(@left.evaluate, @right)
elsif @right.exact? then Multiplication.new(@left, @right.evaluate)
else Multiplication.new(@left, @right)
end
end
def derive(variable)
mult1 = Multiplication.new(@left.derive(variable), @right)
mult2 = Multiplication.new(@left, @right.derive(variable))
addition = Addition.new(mult1, mult2)
addition.simplify
end
end
class Number < Unary
def evaluate(environment = {})
@value
end
def exact?
true
end
def simplify
evaluate
end
def derive(variable)
Number.new(0)
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Sine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Cosine.new(@value)).simplify
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Cosine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Negation.new(Sine.new(@value))).simplify
end
end
class Negation < Unary
def evaluate(environment = {})
-1 * @value.evaluate(environment)
end
def simplify
if exact? then evaluate
else Negation.new(@value)
end
end
def derive(variable)
- Negation.new(@value.derive).simplify
+ Negation.new(@value.derive(variable)).simplify
end
end
class Variable < Unary
def evaluate(environment = {})
if environment.key?(@value) then environment[@value]
else @value
end
end
def exact?
false
end
def simplify
Variable.new(@value)
end
def derive(variable)
if @value == variable then Number.new(1)
else Number.new(0)
end
end
end

Румен обнови решението на 14.11.2012 15:32 (преди над 11 години)

class Expr
def Expr.build(ast)
if ast.is_a?(Array) == false then ast
elsif ast[0] == :number then Number.new(ast[1])
elsif ast[0] == :variable then Variable.new(ast[1])
elsif ast[0] == :+ then Addition.new(ast[1], ast[2])
elsif ast[0] == :* then Multiplication.new(ast[1], ast[2])
elsif ast[0] == :- then Negation.new(ast[1])
elsif ast[0] == :sin then Sine.new(ast[1])
elsif ast[0] == :cos then Cosine.new(ast[1])
else nil
end
end
end
class Unary < Expr
+ attr_reader :value
+
def initialize(value)
@value = Expr.build(value)
end
def exact?
@value.exact?
end
def ==(other)
- @value == other
+ @value == other.value
end
end
class Binary < Expr
+ attr_reader :left, :right
+
def initialize(left, right)
@left = Expr.build(left)
@right = Expr.build(right)
end
def exact?
@left.exact? and @right.exact?
end
def ==(other)
@left == other.left and @right == other.right
end
end
class Addition < Binary
def evaluate(environment = {})
@left.evaluate(environment) + @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Addition.new(@left.evaluate, @right)
elsif @right.exact? then Addition.new(@left, @right.evaluate)
else Addition.new(@left, @right)
end
end
def derive(variable)
addition = Addition.new(@left.derive(variable), @right.derive(variable))
addition.simplify
end
end
class Multiplication < Binary
def evaluate(environment = {})
@left.evaluate(environment) * @right.evaluate(environment)
end
def simplify
if exact? then evaluate
elsif @left.exact? then Multiplication.new(@left.evaluate, @right)
elsif @right.exact? then Multiplication.new(@left, @right.evaluate)
else Multiplication.new(@left, @right)
end
end
def derive(variable)
mult1 = Multiplication.new(@left.derive(variable), @right)
mult2 = Multiplication.new(@left, @right.derive(variable))
addition = Addition.new(mult1, mult2)
addition.simplify
end
end
class Number < Unary
def evaluate(environment = {})
@value
end
def exact?
true
end
def simplify
evaluate
end
def derive(variable)
Number.new(0)
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Sine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Cosine.new(@value)).simplify
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@value.evaluate(environment))
end
def simplify
if exact? then evaluate
else Cosine.new(@value)
end
end
def derive(variable)
Multiplication.new(@value.derive(variable), Negation.new(Sine.new(@value))).simplify
end
end
class Negation < Unary
def evaluate(environment = {})
-1 * @value.evaluate(environment)
end
def simplify
if exact? then evaluate
else Negation.new(@value)
end
end
def derive(variable)
Negation.new(@value.derive(variable)).simplify
end
end
class Variable < Unary
def evaluate(environment = {})
if environment.key?(@value) then environment[@value]
else @value
end
end
def exact?
false
end
def simplify
Variable.new(@value)
end
def derive(variable)
if @value == variable then Number.new(1)
else Number.new(0)
end
end
end