Решение на Трета задача от Явор Лилянов

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

Към профила на Явор Лилянов

Резултати

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

Код

class Expr
attr_reader :expression
def initialize(expression)
@expression = expression
end
def self.build(expression)
Expr.new(expression)
end
def ==(other)
@expression == other.expression
end
def evaluate(values)
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).evaluate(values)
else
Unnary.new(@expression.dup).evaluate(values)
end
end
def simpleTree
if !exact?
[:number, evaluate(1)]
else
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).simpleTree
else
Unnary.new(@expression.dup).simpleTree
end
end
end
def simplify
Expr.new(simpleTree)
end
def exact?
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).exact?
else
Unnary.new(@expression.dup).exact?
end
end
def derive
if !exact?
[:number ,0]
else
if operation == :+ or operation == :*
Binnary.new(@expression.dup).simpleTree
else
Unnary.new(@expression.dup).simpleTree
end
end
end
end
class Binnary < Expr
def evaluate(values)
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).evaluate(values)
when :* then Mult.new(@expression).evaluate(values)
end
end
def simpleTree
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).simpleTree
when :* then Mult.new(@expression).simpleTree
end
end
def exact?
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).exact?
when :* then Mult.new(@expression).exact?
end
end
def derive
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).derive
when :* then Mult.new(@expression).derive
end
end
end
class Plus < Expr
def initialize(expression)
@subExpr1 = expression.first
@subExpr2 = expression.last
@func1 = @subExpr1.first
@func2 = @subExpr1.first
end
def evaluate(values)
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).evaluate(values) + Expr.new(@subExpr2).evaluate(values)
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).evaluate(values) + Unnary.new(@subExpr2).evaluate(values)
else
Expr.new(@subExpr1).evaluate(values) + Expr.new(@subExpr2).evaluate(values)
end
end
def exact?
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).exact? or Unnary.new(@subExpr2).exact?
else
Expr.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
end
end
def simpleTree
if @subExpr1 == [:number, 0]
Expr.new(@subExpr2).simpleTree
elsif @subExpr2 == [:number, 0]
Expr.new(@subExpr1).simpleTree
elsif @func1 == :variable || @func2 == :variable
[:*,@subExpr1,@subExpr2]
elsif @subExpr1 == [:number, 0] || @subExpr2 == [:number, 0]
[:number, 0]
else
Expr.new([:+,Expr.new(@subExpr1).simpleTree, Expr.new(@subExpr2).simpleTree]).simpleTree
end
end
end
class Mult < Expr
def initialize(expression)
@subExpr1 = expression.first
@subExpr2 = expression.last
@func1 = @subExpr1.first
@func2 = @subExpr2.first
end
def evaluate(values)
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1==:-
Unnary.new(@subExpr1).evaluate(values) * Expr.new(@subExpr2).evaluate(values)
elsif @func2 == :number or @func2 == :variable or @func2 == :sin or @func2 == :cos or @func2==:-
Expr.new(@subExpr1).evaluate(values) * Unnary.new(@subExpr2).evaluate(values)
else
Expr.new(@subExpr1).evaluate(values)*Expr.new(@subExpr2).evaluate(values)
end
end
def exact?
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).exact? or Unnary.new(@subExpr2).exact?
else
Expr.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
end
end
def simpleTree
if @subExpr1 == [:number, 1]
Expr.new(@subExpr2).simpleTree
elsif(@subExpr2 == [:number, 1])
Expr.new(@subExpr1).simpleTree
elsif @subExpr1 == [:number, 0] || @subExpr2 == [:number, 0]
[:number, 0]
elsif @func1 == :variable || @func2 == :variable
[:*,@subExpr1,@subExpr2]
else
Expr.new([:*,Expr.new(@subExpr1).simpleTree, Expr.new(@subExpr2).simpleTree]).simpleTree
end
end
end
class Unnary < Expr
def evaluate(values)
case @expression.first
when :number then Number.new(@expression).evaluate
when :variable then Variable.new(@expression).evaluate(values)
when :cos then Cosine.new(@expression).evaluate(values)
when :sin then Sine.new(@expression).evaluate(values)
when :- then Negation.new(@expression).evaluate(values)
end
end
def exact?
case @expression.first
when :number then false
when :variable then true
when :cos then Cosine.new(@expression).exact?
when :sin then Sine.new(@expression).exact?
when :- then Negation.new(@expression).exact?
end
end
def simpleTree
case @expression.first
when :number then @expression
when :variable then @expression
when :cos then Cosine.new(@expression).simpleTree
when :sin then Sine.new(@expression).simpleTree
when :- then Negation.new(@expression).simpleTree
end
end
end
class Number < Unnary
def initialize(expression)
@number = expression.last
end
def evaluate
@number
end
end
class Variable < Unnary
def initialize(expression)
@variable = expression.last
end
def evaluate(values)
if values.key? @variable
values[@variable]
else
raise "The variable '#{@variable}' is not declarated"
end
end
end
class Cosine < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
Math.cos(Expr.new(@subExpression).evaluate(values))
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:cos, Expr.new(@subExpression).simpleTree]
end
end
class Sine < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
Math.sin(Expr.new(@subExpression).evaluate(values))
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:sin, Expr.new(@subExpression).simpleTree]
end
end
class Negation < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
0 - Expr.new(@subExpression).evaluate(values)
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:-, Expr.new(@subExpression).simpleTree]
end
end

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

...F.........

Failures:

  1) Expressions assignment can derive expressions
     Failure/Error: build(string).derive(:x)
     ArgumentError:
       wrong number of arguments (1 for 0)
     # /tmp/d20130203-23049-1hdqb7n/solution.rb:51:in `derive'
     # /tmp/d20130203-23049-1hdqb7n/spec.rb:129:in `derive'
     # /tmp/d20130203-23049-1hdqb7n/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.04671 seconds
13 examples, 1 failure

Failed examples:

rspec /tmp/d20130203-23049-1hdqb7n/spec.rb:160 # Expressions assignment can derive expressions

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

Явор обнови решението на 14.11.2012 15:53 (преди над 11 години)

+class Expr
+ attr_reader :expression
+
+ def initialize(expression)
+ @expression = expression
+ end
+
+ def self.build(expression)
+ Expr.new(expression)
+ end
+
+ def ==(other)
+ @expression == other.expression
+ end
+
+ def evaluate(values)
+ operation = @expression.first
+ if operation == :+ or operation == :*
+ Binnary.new(@expression.dup).evaluate(values)
+ else
+ Unnary.new(@expression.dup).evaluate(values)
+ end
+ end
+
+ def simpleTree
+ if !exact?
+ [:number, evaluate(1)]
+ else
+ operation = @expression.first
+ if operation == :+ or operation == :*
+ Binnary.new(@expression.dup).simpleTree
+ else
+ Unnary.new(@expression.dup).simpleTree
+ end
+ end
+ end
+
+ def simplify
+ Expr.new(simpleTree)
+ end
+
+ def exact?
+ operation = @expression.first
+ if operation == :+ or operation == :*
+ Binnary.new(@expression.dup).exact?
+ else
+ Unnary.new(@expression.dup).exact?
+ end
+ end
+end
+
+class Binnary < Expr
+ def evaluate(values)
+ operation = @expression.shift
+ case operation
+ when :+ then Plus.new(@expression).evaluate(values)
+ when :* then Mult.new(@expression).evaluate(values)
+ end
+ end
+
+ def simpleTree
+ operation = @expression.shift
+ case operation
+ when :+ then Plus.new(@expression).simpleTree
+ when :* then Mult.new(@expression).simpleTree
+ end
+ end
+
+ def exact?
+ operation = @expression.shift
+ case operation
+ when :+ then Plus.new(@expression).exact?
+ when :* then Mult.new(@expression).exact?
+ end
+ end
+end
+
+class Plus < Expr
+ def initialize(expression)
+ @subExpr1 = expression.first
+ @subExpr2 = expression.last
+ @func1 = @subExpr1.first
+ @func2 = @subExpr1.first
+ end
+
+ def evaluate(values)
+ if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
+ Unnary.new(@subExpr1).evaluate(values) + Expr.new(@subExpr2).evaluate(values)
+ elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
+ Expr.new(@subExpr1).evaluate(values) + Unnary.new(@subExpr2).evaluate(values)
+ else
+ Expr.new(@subExpr1).evaluate(values) + Expr.new(@subExpr2).evaluate(values)
+ end
+ end
+
+ def exact?
+ if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
+ Unnary.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
+ elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
+ Expr.new(@subExpr1).exact? or Unnary.new(@subExpr2).exact?
+ else
+ Expr.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
+ end
+ end
+
+ def simpleTree
+ if(@subExpr1 == [:number, 0])
+ Expr.new(@subExpr2).simpleTree
+ elsif(@subExpr2 == [:number, 0])
+ Expr.new(@subExpr1).simpleTree
+ elsif @func1 == :variable || @func2 == :variable
+ [:*,@subExpr1,@subExpr2]
+ elsif @subExpr1 == [:number, 0] || @subExpr2 == [:number, 0]
+ [:number, 0]
+ else
+ Expr.new([:+,Expr.new(@subExpr1).simpleTree, Expr.new(@subExpr2).simpleTree]).simpleTree
+ end
+ end
+end
+
+class Mult < Expr
+ def initialize(expression)
+ @subExpr1=expression.first
+ @subExpr2=expression.last
+ @func1=@subExpr1.first
+ @func2=@subExpr2.first
+ end
+
+ def evaluate(values)
+ if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1==:-
+ Unnary.new(@subExpr1).evaluate(values) * Expr.new(@subExpr2).evaluate(values)
+ elsif @func2 == :number or @func2 == :variable or @func2 == :sin or @func2 == :cos or @func2==:-
+ Expr.new(@subExpr1).evaluate(values) * Unnary.new(@subExpr2).evaluate(values)
+ else
+ Expr.new(@subExpr1).evaluate(values)*Expr.new(@subExpr2).evaluate(values)
+ end
+ end
+
+ def exact?
+ if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
+ Unnary.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
+ elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
+ Expr.new(@subExpr1).exact? or Unnary.new(@subExpr2).exact?
+ else
+ Expr.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
+ end
+ end
+
+ def simpleTree
+ if(@subExpr1 == [:number, 1])
+ Expr.new(@subExpr2).simpleTree
+ elsif(@subExpr2 == [:number, 1])
+ Expr.new(@subExpr1).simpleTree
+ elsif @subExpr1 == [:number, 0] || @subExpr2 == [:number, 0]
+ [:number, 0]
+ elsif @func1 == :variable || @func2 == :variable
+ [:*,@subExpr1,@subExpr2]
+ else
+ Expr.new([:*,Expr.new(@subExpr1).simpleTree, Expr.new(@subExpr2).simpleTree]).simpleTree
+ end
+ end
+end
+
+class Unnary < Expr
+ def evaluate(values)
+ case @expression.first
+ when :number then Number.new(@expression).evaluate
+ when :variable then Variable.new(@expression).evaluate(values)
+ when :cos then Cosine.new(@expression).evaluate(values)
+ when :sin then Sine.new(@expression).evaluate(values)
+ when :- then Negation.new(@expression).evaluate(values)
+ end
+ end
+
+ def exact?
+ case @expression.first
+ when :number then false
+ when :variable then true
+ when :cos then Cosine.new(@expression).exact?
+ when :sin then Sine.new(@expression).exact?
+ when :- then Negation.new(@expression).exact?
+ end
+ end
+
+ def simpleTree
+ case @expression.first
+ when :number then @expression
+ when :variable then @expression
+ when :cos then Cosine.new(@expression).simpleTree
+ when :sin then Sine.new(@expression).simpleTree
+ when :- then Negation.new(@expression).simpleTree
+ end
+ end
+end
+
+class Number < Unnary
+ def initialize(expression)
+ @number = expression.last
+ end
+
+ def evaluate
+ @number
+ end
+end
+
+class Variable < Unnary
+ def initialize(expression)
+ @variable = expression.last
+ end
+
+ def evaluate(values)
+ if(values.key? @variable)
+ values[@variable]
+ else
+ raise "The variable '#{@variable}' is not declarated"
+ end
+ end
+end
+
+class Cosine < Unnary
+ def initialize(expression)
+ expression.flatten!(1).shift
+ @subExpression = expression
+ end
+
+ def evaluate(values)
+ Math.cos(Expr.new(@subExpression).evaluate(values))
+ end
+
+ def exact?
+ Expr.new(@subExpression).exact?
+ end
+
+ def simpleTree
+ [:cos, Expr.new(@subExpression).simpleTree]
+ end
+end
+
+class Sine < Unnary
+ def initialize(expression)
+ expression.flatten!(1).shift
+ @subExpression = expression
+ end
+
+ def evaluate(values)
+ Math.sin(Expr.new(@subExpression).evaluate(values))
+ end
+
+ def exact?
+ Expr.new(@subExpression).exact?
+ end
+
+ def simpleTree
+ [:sin, Expr.new(@subExpression).simpleTree]
+ end
+end
+
+class Negation < Unnary
+ def initialize(expression)
+ expression.flatten!(1).shift
+ @subExpression = expression
+ end
+
+ def evaluate(values)
+ 0 - Expr.new(@subExpression).evaluate(values)
+ end
+
+ def exact?
+ Expr.new(@subExpression).exact?
+ end
+
+ def simpleTree
+ [:-, Expr.new(@subExpression).simpleTree]
+ end
+end

Явор обнови решението на 14.11.2012 16:49 (преди над 11 години)

class Expr
attr_reader :expression
def initialize(expression)
@expression = expression
end
def self.build(expression)
Expr.new(expression)
end
def ==(other)
@expression == other.expression
end
def evaluate(values)
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).evaluate(values)
else
Unnary.new(@expression.dup).evaluate(values)
end
end
def simpleTree
if !exact?
[:number, evaluate(1)]
else
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).simpleTree
else
Unnary.new(@expression.dup).simpleTree
end
end
end
def simplify
Expr.new(simpleTree)
end
def exact?
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).exact?
else
Unnary.new(@expression.dup).exact?
end
end
end
class Binnary < Expr
def evaluate(values)
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).evaluate(values)
when :* then Mult.new(@expression).evaluate(values)
end
end
def simpleTree
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).simpleTree
when :* then Mult.new(@expression).simpleTree
end
end
def exact?
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).exact?
when :* then Mult.new(@expression).exact?
end
end
end
class Plus < Expr
def initialize(expression)
@subExpr1 = expression.first
@subExpr2 = expression.last
@func1 = @subExpr1.first
@func2 = @subExpr1.first
end
def evaluate(values)
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).evaluate(values) + Expr.new(@subExpr2).evaluate(values)
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).evaluate(values) + Unnary.new(@subExpr2).evaluate(values)
else
Expr.new(@subExpr1).evaluate(values) + Expr.new(@subExpr2).evaluate(values)
end
end
def exact?
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).exact? or Unnary.new(@subExpr2).exact?
else
Expr.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
end
end
def simpleTree
if(@subExpr1 == [:number, 0])
Expr.new(@subExpr2).simpleTree
elsif(@subExpr2 == [:number, 0])
Expr.new(@subExpr1).simpleTree
elsif @func1 == :variable || @func2 == :variable
[:*,@subExpr1,@subExpr2]
elsif @subExpr1 == [:number, 0] || @subExpr2 == [:number, 0]
[:number, 0]
else
Expr.new([:+,Expr.new(@subExpr1).simpleTree, Expr.new(@subExpr2).simpleTree]).simpleTree
end
end
end
class Mult < Expr
def initialize(expression)
- @subExpr1=expression.first
- @subExpr2=expression.last
- @func1=@subExpr1.first
- @func2=@subExpr2.first
+ @subExpr1 = expression.first
+ @subExpr2 = expression.last
+ @func1 = @subExpr1.first
+ @func2 = @subExpr2.first
end
def evaluate(values)
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1==:-
Unnary.new(@subExpr1).evaluate(values) * Expr.new(@subExpr2).evaluate(values)
elsif @func2 == :number or @func2 == :variable or @func2 == :sin or @func2 == :cos or @func2==:-
Expr.new(@subExpr1).evaluate(values) * Unnary.new(@subExpr2).evaluate(values)
else
Expr.new(@subExpr1).evaluate(values)*Expr.new(@subExpr2).evaluate(values)
end
end
def exact?
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).exact? or Unnary.new(@subExpr2).exact?
else
Expr.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
end
end
def simpleTree
if(@subExpr1 == [:number, 1])
Expr.new(@subExpr2).simpleTree
elsif(@subExpr2 == [:number, 1])
Expr.new(@subExpr1).simpleTree
elsif @subExpr1 == [:number, 0] || @subExpr2 == [:number, 0]
[:number, 0]
elsif @func1 == :variable || @func2 == :variable
[:*,@subExpr1,@subExpr2]
else
Expr.new([:*,Expr.new(@subExpr1).simpleTree, Expr.new(@subExpr2).simpleTree]).simpleTree
end
end
end
class Unnary < Expr
def evaluate(values)
case @expression.first
when :number then Number.new(@expression).evaluate
when :variable then Variable.new(@expression).evaluate(values)
when :cos then Cosine.new(@expression).evaluate(values)
when :sin then Sine.new(@expression).evaluate(values)
when :- then Negation.new(@expression).evaluate(values)
end
end
def exact?
case @expression.first
when :number then false
when :variable then true
when :cos then Cosine.new(@expression).exact?
when :sin then Sine.new(@expression).exact?
when :- then Negation.new(@expression).exact?
end
end
def simpleTree
case @expression.first
when :number then @expression
when :variable then @expression
when :cos then Cosine.new(@expression).simpleTree
when :sin then Sine.new(@expression).simpleTree
when :- then Negation.new(@expression).simpleTree
end
end
end
class Number < Unnary
def initialize(expression)
@number = expression.last
end
def evaluate
@number
end
end
class Variable < Unnary
def initialize(expression)
@variable = expression.last
end
def evaluate(values)
if(values.key? @variable)
values[@variable]
else
raise "The variable '#{@variable}' is not declarated"
end
end
end
class Cosine < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
Math.cos(Expr.new(@subExpression).evaluate(values))
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:cos, Expr.new(@subExpression).simpleTree]
end
end
class Sine < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
Math.sin(Expr.new(@subExpression).evaluate(values))
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:sin, Expr.new(@subExpression).simpleTree]
end
end
class Negation < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
0 - Expr.new(@subExpression).evaluate(values)
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:-, Expr.new(@subExpression).simpleTree]
end
end

Явор обнови решението на 14.11.2012 16:59 (преди над 11 години)

class Expr
attr_reader :expression
def initialize(expression)
@expression = expression
end
def self.build(expression)
Expr.new(expression)
end
def ==(other)
@expression == other.expression
end
def evaluate(values)
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).evaluate(values)
else
Unnary.new(@expression.dup).evaluate(values)
end
end
def simpleTree
if !exact?
[:number, evaluate(1)]
else
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).simpleTree
else
Unnary.new(@expression.dup).simpleTree
end
end
end
def simplify
Expr.new(simpleTree)
end
def exact?
operation = @expression.first
if operation == :+ or operation == :*
Binnary.new(@expression.dup).exact?
else
Unnary.new(@expression.dup).exact?
end
end
+
+ def derive
+ if !exact?
+ [:number ,0]
+ else
+ if operation == :+ or operation == :*
+ Binnary.new(@expression.dup).simpleTree
+ else
+ Unnary.new(@expression.dup).simpleTree
+ end
+ end
+ end
end
class Binnary < Expr
def evaluate(values)
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).evaluate(values)
when :* then Mult.new(@expression).evaluate(values)
end
end
def simpleTree
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).simpleTree
when :* then Mult.new(@expression).simpleTree
end
end
def exact?
operation = @expression.shift
case operation
when :+ then Plus.new(@expression).exact?
when :* then Mult.new(@expression).exact?
end
end
+
+ def derive
+ operation = @expression.shift
+ case operation
+ when :+ then Plus.new(@expression).derive
+ when :* then Mult.new(@expression).derive
+ end
+ end
end
class Plus < Expr
def initialize(expression)
@subExpr1 = expression.first
@subExpr2 = expression.last
@func1 = @subExpr1.first
@func2 = @subExpr1.first
end
def evaluate(values)
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).evaluate(values) + Expr.new(@subExpr2).evaluate(values)
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).evaluate(values) + Unnary.new(@subExpr2).evaluate(values)
else
Expr.new(@subExpr1).evaluate(values) + Expr.new(@subExpr2).evaluate(values)
end
end
def exact?
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).exact? or Unnary.new(@subExpr2).exact?
else
Expr.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
end
end
def simpleTree
- if(@subExpr1 == [:number, 0])
+ if @subExpr1 == [:number, 0]
Expr.new(@subExpr2).simpleTree
- elsif(@subExpr2 == [:number, 0])
+ elsif @subExpr2 == [:number, 0]
Expr.new(@subExpr1).simpleTree
elsif @func1 == :variable || @func2 == :variable
[:*,@subExpr1,@subExpr2]
elsif @subExpr1 == [:number, 0] || @subExpr2 == [:number, 0]
[:number, 0]
else
Expr.new([:+,Expr.new(@subExpr1).simpleTree, Expr.new(@subExpr2).simpleTree]).simpleTree
end
end
end
class Mult < Expr
def initialize(expression)
@subExpr1 = expression.first
@subExpr2 = expression.last
@func1 = @subExpr1.first
@func2 = @subExpr2.first
end
def evaluate(values)
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1==:-
Unnary.new(@subExpr1).evaluate(values) * Expr.new(@subExpr2).evaluate(values)
elsif @func2 == :number or @func2 == :variable or @func2 == :sin or @func2 == :cos or @func2==:-
Expr.new(@subExpr1).evaluate(values) * Unnary.new(@subExpr2).evaluate(values)
else
Expr.new(@subExpr1).evaluate(values)*Expr.new(@subExpr2).evaluate(values)
end
end
def exact?
if @func1 == :number or @func1 == :variable or @func1 == :sin or @func1 == :cos or @func1 == :-
Unnary.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
elsif @func2 == :number or @func2 == :variable or @func2==:sin or @func2 == :cos or @func2 == :-
Expr.new(@subExpr1).exact? or Unnary.new(@subExpr2).exact?
else
Expr.new(@subExpr1).exact? or Expr.new(@subExpr2).exact?
end
end
def simpleTree
- if(@subExpr1 == [:number, 1])
+ if @subExpr1 == [:number, 1]
Expr.new(@subExpr2).simpleTree
elsif(@subExpr2 == [:number, 1])
Expr.new(@subExpr1).simpleTree
elsif @subExpr1 == [:number, 0] || @subExpr2 == [:number, 0]
[:number, 0]
elsif @func1 == :variable || @func2 == :variable
[:*,@subExpr1,@subExpr2]
else
Expr.new([:*,Expr.new(@subExpr1).simpleTree, Expr.new(@subExpr2).simpleTree]).simpleTree
end
end
end
class Unnary < Expr
def evaluate(values)
case @expression.first
when :number then Number.new(@expression).evaluate
when :variable then Variable.new(@expression).evaluate(values)
when :cos then Cosine.new(@expression).evaluate(values)
when :sin then Sine.new(@expression).evaluate(values)
when :- then Negation.new(@expression).evaluate(values)
end
end
def exact?
case @expression.first
when :number then false
when :variable then true
when :cos then Cosine.new(@expression).exact?
when :sin then Sine.new(@expression).exact?
when :- then Negation.new(@expression).exact?
end
end
def simpleTree
case @expression.first
when :number then @expression
when :variable then @expression
when :cos then Cosine.new(@expression).simpleTree
when :sin then Sine.new(@expression).simpleTree
when :- then Negation.new(@expression).simpleTree
end
end
end
class Number < Unnary
def initialize(expression)
@number = expression.last
end
def evaluate
@number
end
end
class Variable < Unnary
def initialize(expression)
@variable = expression.last
end
def evaluate(values)
- if(values.key? @variable)
+ if values.key? @variable
values[@variable]
else
raise "The variable '#{@variable}' is not declarated"
end
end
end
class Cosine < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
Math.cos(Expr.new(@subExpression).evaluate(values))
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:cos, Expr.new(@subExpression).simpleTree]
end
end
class Sine < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
Math.sin(Expr.new(@subExpression).evaluate(values))
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:sin, Expr.new(@subExpression).simpleTree]
end
end
class Negation < Unnary
def initialize(expression)
expression.flatten!(1).shift
@subExpression = expression
end
def evaluate(values)
0 - Expr.new(@subExpression).evaluate(values)
end
def exact?
Expr.new(@subExpression).exact?
end
def simpleTree
[:-, Expr.new(@subExpression).simpleTree]
end
end