Решение на Трета задача от Живко Чобанов

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

Към профила на Живко Чобанов

Резултати

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

Код

class Test3 < MiniTest::Unit::TestCase
def test_=
a = Expr.build [:+, [:number, 2], [:number, 3]]
b = Expr.build [:+, [:number, 2], [:number, 3]]
c = Expr.build [:+, [:number, 33333], [:number, 3]]
d = Expr.build [:+, [:number, 3], [:number, 2]]
assert a == b, '=='
assert not(a == c), 'not =='
assert not(a == d), 'not =='
end
def test_evaluate_binary
a = Expr.build [:+, [:number, 2], [:number, 3]]
b = Expr.build [:+, [:variable, :x], [:variable, :y]]
c = Expr.build [:*, [:variable, :x], [:number, 3]]
d = Expr.build [:*, [:variable, :x], [:+, [:variable, :x], [:variable, :y]]]
assert_equal a.evaluate, 5, 'no variables'
assert_equal b.evaluate(x: 1, y: 2), 3, 'x y'
assert_equal c.evaluate(x: 2), 6, 'x * 3'
assert_equal d.evaluate(x: 2, y: 3), 10, 'x * (x+y)'
end
def test_evaluate_unary
e = Expr.build [:-, [:number, 2]]
f = Expr.build [:sin, [:number, Math::PI / 6]]
g = Expr.build [:cos, [:number, Math::PI / 6]]
assert_equal e.evaluate, -2, 'negation of 2'
assert_equal f.evaluate, Math.sin(Math::PI / 6), 'sin 30'
assert_equal g.evaluate, Math.cos(Math::PI / 6), 'sin 30'
end
def test_simplify_no_trigonometry
a = Expr.build [:number, 2]
b = Expr.build [:+, [:number, 2], [:number, 0]]
c = Expr.build [:*, [:number, 2], [:number, 1]]
assert_equal a.simplify, a, 'number'
assert_equal b.simplify, a, 'sum'
assert_equal c.simplify.tree, [:number, 2], 'multipl'
end
def test_simplify_trigonometry
zero = Expr.build [:number, 0]
a = Expr.build [:sin, [:number, 0]]
b = Expr.build [:sin, [:number, Math::PI]]
c = Expr.build [:cos, [:number, Math::PI / 2]]
assert_equal a.simplify, zero, 'sin 0'
assert_equal b.simplify, zero, 'sin pi'
assert_equal c.simplify, zero, 'cos pi/2'
end
def test_derivative
a = Expr.build [:variable, :x]
b = Expr.build [:number, 3]
c = Expr.build [:*, b.tree, a.tree]
assert_equal a.derive(:x), Expr.build([:number, 1]), "x'"
assert_equal b.derive(:x), Expr.build([:number, 0]), "3'"
assert_equal c.derive(:x), Expr.build([:number, 3]), "3x'"
end
end
module Tree
def label
self.class::LABEL
end
end
class Expr
def Expr.build(tree)
expr_main_classes = [Number, Variable, Negation, Sine, Cosine, Addition, Multiplication]
expr_main_classes.each do |expr_class|
if expr_class::LABEL == tree[0]
return expr_class.new(*tree.drop(1))
end
end
end
def ==(other)
tree == other.tree
end
def evaluate(environment={})
@linguistic_construction.evaluate environment
end
def simplify
@linguistic_construction.simplify
end
end
class Unary < Expr
def initialize(tree)
@expr = Expr.build tree
end
def simplify
self
end
def tree
[label, value]
end
end
class Binary < Expr
def initialize(tree1, tree2)
@expr1 = Expr.build tree1
@expr2 = Expr.build tree2
end
def evaluate(environment={}, operation)
operation.to_proc.(
@expr1.evaluate(environment),
@expr2.evaluate(environment)
)
end
def tree
[label, @expr1.tree, @expr2.tree]
end
end
class Number < Unary
LABEL = :number
include Tree
def initialize(number)
@number = number
end
def evaluate(environment={})
@number
end
def value
@number
end
def derive(variable_name)
Expr.build [:number, 0]
end
end
class Variable < Unary
LABEL = :variable
include Tree
def initialize(variable_name)
@variable_name = variable_name
end
def evaluate(environment={})
environment.fetch @variable_name, "undefined variable #{@variable_name}"
end
def value
@variable_name
end
def derive(variable_name)
if variable_name == @variable_name
Expr.build [:number, 1]
else
self
end
end
end
class Negation < Unary
LABEL = :-
include Tree
def initialize(tree)
super
end
def evaluate(environment={})
-1 * @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if simplified_expr.tree == [:number, 0]
return simplified_expr
else
Expr.build [LABEL, simplified_expr.tree]
end
end
def value
@expr.tree
end
def derive(variable_name)
Expr.build [LABEL, @expr.derive(variable_name).tree]
end
end
class Sine < Unary
LABEL = :sin
include Tree
attr_reader :expr
def initialize(tree)
super
end
def evaluate(environment={})
Math.sin @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if [[:number, 0],[:number, Math::PI]].include? simplified_expr.tree
return Expr.build [:number, 0]
else
Expr.build [LABEL, simplified_expr.tree]
end
end
def value
@expr.tree
end
def derive(variable_name)
Expr.build [:*,
simplify.expr.derive(variable_name).tree,
[:cos, simplify.expr]]
end
end
class Cosine < Unary
LABEL = :cos
include Tree
attr_reader :expr
def initialize(tree)
super
end
def evaluate(environment={})
Math.cos @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if simplified_expr.tree == [:number, Math::PI / 2]
return Expr.build [:number, 0]
else
Expr.build [LABEL, simplified_expr.tree]
end
end
def value
@expr.tree
end
def derive(variable_name)
Expr.build [:*,
simplify.expr.derive(variable_name).tree,
[:-, [:sin, simplify.expr]]]
end
end
class Addition < Binary
LABEL = :+
include Tree
def initialize(tree1, tree2)
super
end
def evaluate(environment={})
super environment, :+
end
def simplify
[@expr1, @expr2].map(&:simplify)
if @expr1.tree == [:number, 0]
return @expr2
elsif @expr2.tree == [:number, 0]
return @expr1
end
if @expr1.tree[0] == :number and @expr2.tree[0] == :number
return Expr.build [:number, @expr1.evaluate + @expr2.evaluate]
end
self
end
def derive(variable_name)
Expr.build [:+,
simplify.expr1.derive(variable_name).tree,
simplify.expr2.derive(variable_name).tree]
end
end
class Multiplication < Binary
LABEL = :*
include Tree
attr_reader :expr1, :expr2
def initialize(tree1, tree2)
super
end
def evaluate(environment={})
super environment, :*
end
def simplify
[@expr1, @expr2].map(&:simplify)
if @expr1.tree == [:number, 1]
return @expr2
elsif @expr2.tree == [:number, 1]
return @expr1
end
if @expr1.tree[0] == :number and @expr2.tree[0] == :number
return Expr.build [:number, @expr1.evaluate * @expr2.evaluate]
end
self
end
def derive(variable_name)
Expr.build [:+,
[:*, simplify.expr1.derive(variable_name).tree, simplify.expr2.tree],
[:*, simplify.expr2.derive(variable_name).tree, simplify.expr1.tree]]
end
end

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

/tmp/d20130203-23049-tylzr4/solution.rb:1:in `<top (required)>': uninitialized constant MiniTest (NameError)
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/configuration.rb:434:in `require'
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/configuration.rb:434:in `block in requires='
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/configuration.rb:434:in `map'
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/configuration.rb:434:in `requires='
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/configuration_options.rb:20:in `block in configure'
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/configuration_options.rb:19:in `each'
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/configuration_options.rb:19:in `configure'
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/command_line.rb:21:in `run'
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/runner.rb:69:in `run'
	from /data/rails/evans-2012/shared/bundled_gems/ruby/1.9.1/gems/rspec-core-2.11.0/lib/rspec/core/runner.rb:8:in `block in autorun'

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

Живко обнови решението на 14.11.2012 11:10 (преди около 12 години)

+module Tree
+ def label
+ self.class::LABEL
+ end
+end
+
+class Expr
+ def Expr.build(tree)
+ expr_main_classes = [Number, Variable, Negation, Sine, Cosine, Addition, Multiplication]
+ expr_main_classes.each do |expr_class|
+ if expr_class::LABEL == tree[0]
+ return expr_class.new(*tree.drop(1))
+ end
+ end
+ end
+
+ def ==(other)
+ tree == other.tree
+ end
+
+ def evaluate(environment={})
+ @linguistic_construction.evaluate environment
+ end
+
+ def simplify
+ @linguistic_construction.simplify
+ end
+end
+
+class Unary < Expr
+ def initialize(tree)
+ @expr = Expr.build tree
+ end
+
+ def simplify
+ self
+ end
+
+ def tree
+ [label, value]
+ end
+end
+
+class Binary < Expr
+ def initialize(tree1, tree2)
+ @expr1 = Expr.build tree1
+ @expr2 = Expr.build tree2
+ end
+
+ def evaluate(environment={}, operation)
+ operation.to_proc.(
+ @expr1.evaluate(environment),
+ @expr2.evaluate(environment)
+ )
+ end
+
+ def tree
+ [label, @expr1.tree, @expr2.tree]
+ end
+end
+
+class Number < Unary
+ LABEL = :number
+
+ include Tree
+
+ def initialize(number)
+ @number = number
+ end
+
+ def evaluate(environment={})
+ @number
+ end
+
+ def value
+ @number
+ end
+end
+
+class Variable < Unary
+ LABEL = :variable
+
+ include Tree
+
+ def initialize(variable_name)
+ @variable_name = variable_name
+ end
+
+ def evaluate(environment={})
+ environment.fetch @variable_name, "undefined variable #{@variable_name}"
+ end
+
+ def value
+ @variable_name
+ end
+end
+
+class Negation < Unary
+ LABEL = :-
+
+ include Tree
+
+ def initialize(tree)
+ super
+ end
+
+ def evaluate(environment={})
+ -1 * @expr.evaluate(environment)
+ end
+
+ def simplify
+ simplified_expr = @expr.simplify
+ if simplified_expr.tree == [:number, 0]
+ return simplified_expr
+ else
+ @expr = simplified_expr
+ end
+ end
+
+ def value
+ @expr.tree
+ end
+end
+
+class Sine < Unary
+ LABEL = :sin
+
+ include Tree
+
+ def initialize(tree)
+ super
+ end
+
+ def evaluate(environment={})
+ Math.sin @expr.evaluate(environment)
+ end
+
+ def simplify
+ simplified_expr = @expr.simplify
+ if [[:number, 0],[:number, Math::PI]].include? simplified_expr.tree
+ return Expr.build [:number, 0]
+ else
+ @expr = simplified_expr
+ end
+ end
+
+ def value
+ @expr.tree
+ end
+end
+
+class Cosine < Unary
+ LABEL = :cos
+
+ include Tree
+
+ def initialize(tree)
+ super
+ end
+
+ def evaluate(environment={})
+ Math.cos @expr.evaluate(environment)
+ end
+
+ def simplify
+ simplified_expr = @expr.simplify
+ if simplified_expr.tree == [:number, Math::PI / 2]
+ return Expr.build [:number, 0]
+ else
+ @expr = simplified_expr
+ end
+ end
+
+ def value
+ @expr.tree
+ end
+end
+
+class Addition < Binary
+ LABEL = :+
+
+ include Tree
+
+ def initialize(tree1, tree2)
+ super
+ end
+
+ def evaluate(environment={})
+ super environment, :+
+ end
+
+ def simplify
+ [@expr1, @expr2].map(&:simplify)
+ if @expr1.tree == [:number, 0]
+ return @expr2
+ elsif @expr2.tree == [:number, 0]
+ return @expr1
+ end
+ if @expr1.tree[0] == :number and @expr2.tree[0] == :number
+ return Expr.build [:number, @expr1.evaluate + @expr2.evaluate]
+ end
+ end
+end
+
+class Multiplication < Binary
+ LABEL = :*
+
+ include Tree
+
+ def initialize(tree1, tree2)
+ super
+ end
+
+ def evaluate(environment={})
+ super environment, :*
+ end
+
+ def simplify
+ [@expr1, @expr2].map(&:simplify)
+ if @expr1.tree == [:number, 1]
+ return @expr2
+ elsif @expr2.tree == [:number, 1]
+ return @expr1
+ end
+ if @expr1.tree[0] == :number and @expr2.tree[0] == :number
+ return Expr.build [:number, @expr1.evaluate * @expr2.evaluate]
+ end
+ end
+end

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

+class Test3 < MiniTest::Unit::TestCase
+ def test_=
+ a = Expr.build [:+, [:number, 2], [:number, 3]]
+
+ b = Expr.build [:+, [:number, 2], [:number, 3]]
+ c = Expr.build [:+, [:number, 33333], [:number, 3]]
+ d = Expr.build [:+, [:number, 3], [:number, 2]]
+
+ assert a == b, '=='
+ assert not(a == c), 'not =='
+ assert not(a == d), 'not =='
+ end
+
+ def test_evaluate_binary
+ a = Expr.build [:+, [:number, 2], [:number, 3]]
+ b = Expr.build [:+, [:variable, :x], [:variable, :y]]
+ c = Expr.build [:*, [:variable, :x], [:number, 3]]
+ d = Expr.build [:*, [:variable, :x], [:+, [:variable, :x], [:variable, :y]]]
+
+ assert_equal a.evaluate, 5, 'no variables'
+ assert_equal b.evaluate(x: 1, y: 2), 3, 'x y'
+ assert_equal c.evaluate(x: 2), 6, 'x * 3'
+ assert_equal d.evaluate(x: 2, y: 3), 10, 'x * (x+y)'
+ end
+
+ def test_evaluate_unary
+ e = Expr.build [:-, [:number, 2]]
+ f = Expr.build [:sin, [:number, Math::PI / 6]]
+ g = Expr.build [:cos, [:number, Math::PI / 6]]
+
+ assert_equal e.evaluate, -2, 'negation of 2'
+ assert_equal f.evaluate, Math.sin(Math::PI / 6), 'sin 30'
+ assert_equal g.evaluate, Math.cos(Math::PI / 6), 'sin 30'
+ end
+
+ def test_simplify
+ a = Expr.build [:number, 2]
+ b = Expr.build [:+, [:number, 2], [:number, 0]]
+
+ assert_equal a.simplify, a, 'number'
+ assert_equal b.simplify, a, 'number'
+ end
+end
+
module Tree
def label
self.class::LABEL
end
end
class Expr
def Expr.build(tree)
expr_main_classes = [Number, Variable, Negation, Sine, Cosine, Addition, Multiplication]
expr_main_classes.each do |expr_class|
if expr_class::LABEL == tree[0]
return expr_class.new(*tree.drop(1))
end
end
end
def ==(other)
tree == other.tree
end
def evaluate(environment={})
@linguistic_construction.evaluate environment
end
def simplify
@linguistic_construction.simplify
end
end
class Unary < Expr
def initialize(tree)
@expr = Expr.build tree
end
def simplify
self
end
def tree
[label, value]
end
end
class Binary < Expr
def initialize(tree1, tree2)
@expr1 = Expr.build tree1
@expr2 = Expr.build tree2
end
def evaluate(environment={}, operation)
operation.to_proc.(
@expr1.evaluate(environment),
@expr2.evaluate(environment)
)
end
def tree
[label, @expr1.tree, @expr2.tree]
end
end
class Number < Unary
LABEL = :number
include Tree
def initialize(number)
@number = number
end
def evaluate(environment={})
@number
end
def value
@number
end
end
class Variable < Unary
LABEL = :variable
include Tree
def initialize(variable_name)
@variable_name = variable_name
end
def evaluate(environment={})
environment.fetch @variable_name, "undefined variable #{@variable_name}"
end
def value
@variable_name
end
end
class Negation < Unary
LABEL = :-
include Tree
def initialize(tree)
super
end
def evaluate(environment={})
-1 * @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if simplified_expr.tree == [:number, 0]
return simplified_expr
else
@expr = simplified_expr
end
end
def value
@expr.tree
end
end
class Sine < Unary
LABEL = :sin
include Tree
def initialize(tree)
super
end
def evaluate(environment={})
Math.sin @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if [[:number, 0],[:number, Math::PI]].include? simplified_expr.tree
return Expr.build [:number, 0]
else
@expr = simplified_expr
end
end
def value
@expr.tree
end
end
class Cosine < Unary
LABEL = :cos
include Tree
def initialize(tree)
super
end
def evaluate(environment={})
Math.cos @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if simplified_expr.tree == [:number, Math::PI / 2]
return Expr.build [:number, 0]
else
@expr = simplified_expr
end
end
def value
@expr.tree
end
end
class Addition < Binary
LABEL = :+
include Tree
def initialize(tree1, tree2)
super
end
def evaluate(environment={})
super environment, :+
end
def simplify
[@expr1, @expr2].map(&:simplify)
if @expr1.tree == [:number, 0]
return @expr2
elsif @expr2.tree == [:number, 0]
return @expr1
end
if @expr1.tree[0] == :number and @expr2.tree[0] == :number
return Expr.build [:number, @expr1.evaluate + @expr2.evaluate]
end
end
end
class Multiplication < Binary
LABEL = :*
include Tree
def initialize(tree1, tree2)
super
end
def evaluate(environment={})
super environment, :*
end
def simplify
[@expr1, @expr2].map(&:simplify)
if @expr1.tree == [:number, 1]
return @expr2
elsif @expr2.tree == [:number, 1]
return @expr1
end
if @expr1.tree[0] == :number and @expr2.tree[0] == :number
return Expr.build [:number, @expr1.evaluate * @expr2.evaluate]
end
end
end

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

class Test3 < MiniTest::Unit::TestCase
def test_=
a = Expr.build [:+, [:number, 2], [:number, 3]]
b = Expr.build [:+, [:number, 2], [:number, 3]]
c = Expr.build [:+, [:number, 33333], [:number, 3]]
d = Expr.build [:+, [:number, 3], [:number, 2]]
assert a == b, '=='
assert not(a == c), 'not =='
assert not(a == d), 'not =='
end
def test_evaluate_binary
a = Expr.build [:+, [:number, 2], [:number, 3]]
b = Expr.build [:+, [:variable, :x], [:variable, :y]]
c = Expr.build [:*, [:variable, :x], [:number, 3]]
d = Expr.build [:*, [:variable, :x], [:+, [:variable, :x], [:variable, :y]]]
assert_equal a.evaluate, 5, 'no variables'
assert_equal b.evaluate(x: 1, y: 2), 3, 'x y'
assert_equal c.evaluate(x: 2), 6, 'x * 3'
assert_equal d.evaluate(x: 2, y: 3), 10, 'x * (x+y)'
end
def test_evaluate_unary
e = Expr.build [:-, [:number, 2]]
f = Expr.build [:sin, [:number, Math::PI / 6]]
g = Expr.build [:cos, [:number, Math::PI / 6]]
assert_equal e.evaluate, -2, 'negation of 2'
assert_equal f.evaluate, Math.sin(Math::PI / 6), 'sin 30'
assert_equal g.evaluate, Math.cos(Math::PI / 6), 'sin 30'
end
- def test_simplify
+ def test_simplify_no_trigonometry
a = Expr.build [:number, 2]
b = Expr.build [:+, [:number, 2], [:number, 0]]
+ c = Expr.build [:*, [:number, 2], [:number, 1]]
assert_equal a.simplify, a, 'number'
- assert_equal b.simplify, a, 'number'
+ assert_equal b.simplify, a, 'sum'
+ assert_equal c.simplify.tree, [:number, 2], 'multipl'
end
+
+ def test_simplify_trigonometry
+ zero = Expr.build [:number, 0]
+ a = Expr.build [:sin, [:number, 0]]
+ b = Expr.build [:sin, [:number, Math::PI]]
+ c = Expr.build [:cos, [:number, Math::PI / 2]]
+
+ assert_equal a.simplify, zero, 'sin 0'
+ assert_equal b.simplify, zero, 'sin pi'
+ assert_equal c.simplify, zero, 'cos pi/2'
+ end
+
+ def test_derivative
+ a = Expr.build [:variable, :x]
+ b = Expr.build [:number, 3]
+ c = Expr.build [:*, b.tree, a.tree]
+
+ assert_equal a.derive(:x), Expr.build([:number, 1]), "x'"
+ assert_equal b.derive(:x), Expr.build([:number, 0]), "3'"
+ assert_equal c.derive(:x), Expr.build([:number, 3]), "3x'"
+ end
end
module Tree
def label
self.class::LABEL
end
end
class Expr
def Expr.build(tree)
expr_main_classes = [Number, Variable, Negation, Sine, Cosine, Addition, Multiplication]
expr_main_classes.each do |expr_class|
if expr_class::LABEL == tree[0]
return expr_class.new(*tree.drop(1))
end
end
end
def ==(other)
tree == other.tree
end
def evaluate(environment={})
@linguistic_construction.evaluate environment
end
def simplify
@linguistic_construction.simplify
end
end
class Unary < Expr
def initialize(tree)
@expr = Expr.build tree
end
def simplify
self
end
def tree
[label, value]
end
end
class Binary < Expr
def initialize(tree1, tree2)
@expr1 = Expr.build tree1
@expr2 = Expr.build tree2
end
def evaluate(environment={}, operation)
operation.to_proc.(
@expr1.evaluate(environment),
@expr2.evaluate(environment)
)
end
def tree
[label, @expr1.tree, @expr2.tree]
end
end
class Number < Unary
LABEL = :number
include Tree
def initialize(number)
@number = number
end
def evaluate(environment={})
@number
end
def value
@number
end
+
+ def derive(variable_name)
+ Expr.build [:number, 0]
+ end
end
class Variable < Unary
LABEL = :variable
include Tree
def initialize(variable_name)
@variable_name = variable_name
end
def evaluate(environment={})
environment.fetch @variable_name, "undefined variable #{@variable_name}"
end
def value
@variable_name
end
+
+ def derive(variable_name)
+ if variable_name == @variable_name
+ Expr.build [:number, 1]
+ else
+ self
+ end
+ end
end
class Negation < Unary
LABEL = :-
include Tree
def initialize(tree)
super
end
def evaluate(environment={})
-1 * @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if simplified_expr.tree == [:number, 0]
return simplified_expr
else
- @expr = simplified_expr
+ Expr.build [LABEL, simplified_expr.tree]
end
end
def value
@expr.tree
end
+
+ def derive(variable_name)
+ Expr.build [LABEL, @expr.derive(variable_name).tree]
+ end
end
class Sine < Unary
LABEL = :sin
include Tree
+ attr_reader :expr
+
def initialize(tree)
super
end
def evaluate(environment={})
Math.sin @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if [[:number, 0],[:number, Math::PI]].include? simplified_expr.tree
return Expr.build [:number, 0]
else
- @expr = simplified_expr
+ Expr.build [LABEL, simplified_expr.tree]
end
end
def value
@expr.tree
end
+
+ def derive(variable_name)
+ Expr.build [:*,
+ simplify.expr.derive(variable_name).tree,
+ [:cos, simplify.expr]]
+ end
end
class Cosine < Unary
LABEL = :cos
include Tree
+ attr_reader :expr
+
def initialize(tree)
super
end
def evaluate(environment={})
Math.cos @expr.evaluate(environment)
end
def simplify
simplified_expr = @expr.simplify
if simplified_expr.tree == [:number, Math::PI / 2]
return Expr.build [:number, 0]
else
- @expr = simplified_expr
+ Expr.build [LABEL, simplified_expr.tree]
end
end
def value
@expr.tree
end
+
+ def derive(variable_name)
+ Expr.build [:*,
+ simplify.expr.derive(variable_name).tree,
+ [:-, [:sin, simplify.expr]]]
+ end
end
class Addition < Binary
LABEL = :+
include Tree
def initialize(tree1, tree2)
super
end
def evaluate(environment={})
super environment, :+
end
def simplify
[@expr1, @expr2].map(&:simplify)
if @expr1.tree == [:number, 0]
return @expr2
elsif @expr2.tree == [:number, 0]
return @expr1
end
if @expr1.tree[0] == :number and @expr2.tree[0] == :number
return Expr.build [:number, @expr1.evaluate + @expr2.evaluate]
end
+ self
end
+
+ def derive(variable_name)
+ Expr.build [:+,
+ simplify.expr1.derive(variable_name).tree,
+ simplify.expr2.derive(variable_name).tree]
+ end
end
class Multiplication < Binary
LABEL = :*
include Tree
+ attr_reader :expr1, :expr2
+
def initialize(tree1, tree2)
super
end
def evaluate(environment={})
super environment, :*
end
def simplify
[@expr1, @expr2].map(&:simplify)
if @expr1.tree == [:number, 1]
return @expr2
elsif @expr2.tree == [:number, 1]
return @expr1
end
if @expr1.tree[0] == :number and @expr2.tree[0] == :number
return Expr.build [:number, @expr1.evaluate * @expr2.evaluate]
end
+ self
end
-end
+
+ def derive(variable_name)
+ Expr.build [:+,
+ [:*, simplify.expr1.derive(variable_name).tree, simplify.expr2.tree],
+ [:*, simplify.expr2.derive(variable_name).tree, simplify.expr1.tree]]
+ end
+end