Решение на Трета задача от Филарета Йорданова

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

Към профила на Филарета Йорданова

Резултати

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

Код

class Expr
def self.build(expression)
operation,a,b = expression
case operation
when :+ then Addition.build a,b
when :* then Multiplication.build a,b
when :- then Negation.build a
when :sin then Sine.build a
when :cos then Cosine.build a
when :variable then Variable.new a
when :number then Number.new a
end
end
def *(other)
Multiplication.new self, other
end
def +(other)
Addition.new self, other
end
def -@
Negation.new self
end
end
class Negation < Expr
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def self.build(operand)
a = Expr.build operand
new a
end
def evaluate(environment)
negative = @operand.evaluate environment
- negative
end
def exact?
@operand.exact?
end
def simplify
if exact?
@operand.simplify
else
Number.new - operand
end
end
def derive(variable)
result = operand.derive variable
- result.simplify
end
def ==(other)
if other.instance_of? Negation
@operand == other.operand
else
false
end
end
end
class Variable < Expr
attr_accessor :variable
def initialize(variable)
@variable = variable
end
def derive(variable)
if @variable == variable
Number.new 1
else
Number.new 0
end
end
def evaluate(environment)
environment.each{ |key,value| if @variable == key then @variable = value end }
@variable
end
def simplify
Variable.new variable
end
def exact?
true
end
def ==(other)
if other.instance_of? Variable
@variable == other.variable
else
false
end
end
end
class Number < Expr
attr_accessor :number
def initialize(number)
@number = number
end
def derive(variable)
Number.new 0
end
def simplify
Number.new @number
end
def exact?
false
end
def evaluate(environment)
@number
end
def ==(other)
if other.instance_of? Number
@number == other.number
else
false
end
end
end
class Sine < Expr
attr_accessor :argument
def initialize(argument)
@argument = argument
end
def self.build(operand)
a = Expr.build operand
new a
end
def evaluate(environment)
Math.sin(@argument.evaluate environment)
end
def derive(variable)
first = Cosine.new argument.derive variable
second = (Variable.new variable).derive variable
result = first * second
result.simplify
end
def simplify
if @argument.exact? then @argument.simplify
elsif @argument.number == 0 then Number.new 0
elsif @argument.number == 90 then Number.new 1
end
end
def exact?
@argument.exact?
end
def ==(other)
if other.instance_of? Sine
@argument == other.argument
else
false
end
end
end
class Cosine < Expr
attr_accessor :argument
def initialize(argument)
@argument = argument
end
def self.build(operand)
a = Expr.build operand
new a
end
def evaluate(environment)
Math.cos(@argument.evaluate environment)
end
def derive(variable)
first = Sine.new argument.derive variable
second = (Variable.new variable).derive variable
result = first * - second
result.simplify
end
def simplify
if @argument.exact? then @argument.simplify
elsif @argument.number == 0 then Number.new 1
elsif @argument.number == 90 then Number.new 0
end
end
def exact?
@argument.exact?
end
def ==(other)
if other.instance_of? Cosine
@argument == other.argument
else
false
end
end
end
class Addition < Expr
attr_accessor :addend_1, :addend_2
def initialize(operand_1,operand_2)
@addend_1 = operand_1
@addend_2 = operand_2
end
def self.build(operand_1,operand_2)
a = Expr.build operand_1
b = Expr.build operand_2
new a,b
end
def derive(variable)
first = addend_1.derive variable
second = addend_2.derive variable
result = first + second
result.simplify
end
def simplify
if @addend_1.instance_of? Number and @addend_2.instance_of? Number then
Number.new @addend_1.number + @addend_2.number
elsif @addend_1.instance_of? Number and @addend_1.number == 0 then @addend_2.simplify
elsif @addend_2.instance_of? Number and @addend_2.number == 0 then @addend_1.simplify
elsif @addend_1.exact? then @addend_1.simplify + @addend_2
elsif @addend_2.exact? then @addend_1 + @addend_2.simplify
elsif @addend_1.exact? then @addend_1.simplify + @addend_2.simplify
end
end
def exact?
@addend_1.exact? or @addend_2.exact?
end
def evaluate(environment)
first = @addend_1.evaluate environment
second = @addend_2.evaluate environment
first + second
end
def ==(other)
if other.instance_of? Addition
@addend_1 == other.addend_1 and @addend_2 == other.addend_2
else
false
end
end
end
class Multiplication < Expr
attr_accessor :multiplicand, :multiplier
def initialize(operand_1,operand_2)
@multiplicand = operand_1
@multiplier = operand_2
end
def self.build(operand_1,operand_2)
a = Expr.build operand_1
b = Expr.build operand_2
new a,b
end
def derive(variable)
first = multiplicand.derive variable
second = multiplier.derive variable
derived_1 = Multiplication.new first, multiplier
derived_2 = Multiplication.new multiplicand, second
result = derived_1 + derived_2
result.simplify
end
def simplify
unless @multiplicand.exact?
if @multiplicand.number == 0 then @multiplicand.simplify
elsif @multiplicand.number == 1 then @multiplier.simplify
elsif @multiplicand.instance_of? Number then @multiplier.simplify
end
else
if @multiplier.exact? then @multiplicand.simplify * @multilier.simplify
elsif @multiplier.number == 0 then @multiplier.simplify
elsif @multiplier.number == 1 then @multiplicand.simplify
elsif @multiplier.instance_of? Number then @multiplicand.simplify
end
end
end
def exact?
@multiplicand.exact? or @multiplier.exact?
end
def evaluate(environment)
first = @multiplicand.evaluate environment
second = @multiplier.evaluate environment
first * second
end
def ==(other)
if other.instance_of? Multiplication
@multiplicand == other.multiplicand and @multiplier == other.multiplier
else
false
end
end
end

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

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

Failures:

  1) Expressions assignment can derive expressions
     Failure/Error: derive('x * x').should eq build('x + x')
       
       expected: #<Addition:0xa3edfb4 @addend_1=#<Variable:0xa3ee054 @variable=:x>, @addend_2=#<Variable:0xa3ee040 @variable=:x>>
            got: #<Addition:0xa3ef828 @addend_1=#<Variable:0xa3ef83c @variable=:x>, @addend_2=#<Multiplication:0xa3ef8c8 @multiplicand=#<Variable:0xa3ef968 @variable=:x>, @multiplier=#<Number:0xa3ef8f0 @number=1>>>
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,7 @@
       -#<Addition:0xa3edfb4
       - @addend_1=#<Variable:0xa3ee054 @variable=:x>,
       - @addend_2=#<Variable:0xa3ee040 @variable=:x>>
       +#<Addition:0xa3ef828
       + @addend_1=#<Variable:0xa3ef83c @variable=:x>,
       + @addend_2=
       +  #<Multiplication:0xa3ef8c8
       +   @multiplicand=#<Variable:0xa3ef968 @variable=:x>,
       +   @multiplier=#<Number:0xa3ef8f0 @number=1>>>
     # /tmp/d20130203-23049-vap2a4/spec.rb:165: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.05907 seconds
13 examples, 1 failure

Failed examples:

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

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

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

+class Expr
+ def self.build(expression)
+ operation,a,b = expression
+ case operation
+ when :+ then Addition.build a,b
+ when :* then Multiplication.build a,b
+ when :- then Negation.build a
+ when :sin then Sine.build a
+ when :cos then Cosine.build a
+ when :variable then Variable.new a
+ when :number then Number.new a
+ end
+ end
+
+ def *(other)
+ Multiplication.new self, other
+ end
+
+ def +(other)
+ Addition.new self, other
+ end
+
+ def -@
+ Negation.new self
+ end
+end
+
+class Negation < Expr
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def self.build(operand)
+ a = Expr.build operand
+ new a
+ end
+
+ def evaluate(environment)
+ negative = @operand.evaluate environment
+ - negative
+ end
+
+ def exact?
+ @operand.exact?
+ end
+
+ def simplify
+ if exact?
+ @operand.simplify
+ else
+ Number.new - operand
+ end
+ end
+
+ def derive(variable)
+ result = operand.derive variable
+ - result.simplify
+ end
+
+ def ==(other)
+ if other.instance_of? Negation
+ @operand == other.operand
+ else
+ false
+ end
+ end
+end
+
+class Variable < Expr
+ attr_accessor :variable
+
+ def initialize(variable)
+ @variable = variable
+ end
+
+ def derive(variable)
+ if @variable == variable
+ Number.new 1
+ else
+ Number.new 0
+ end
+ end
+
+ def evaluate(environment)
+ environment.each{ |key,value| if @variable == key then @variable = value end }
+ @variable
+ end
+
+ def simplify
+ Variable.new variable
+ end
+
+ def exact?
+ true
+ end
+
+ def ==(other)
+ if other.instance_of? Variable
+ @variable == other.variable
+ else
+ false
+ end
+ end
+end
+
+class Number < Expr
+ attr_accessor :number
+
+ def initialize(number)
+ @number = number
+ end
+
+ def derive(variable)
+ Number.new 0
+ end
+
+ def simplify
+ Number.new @number
+ end
+
+ def exact?
+ false
+ end
+
+ def evaluate(environment)
+ @number
+ end
+
+ def ==(other)
+ if other.instance_of? Number
+ @number == other.number
+ else
+ false
+ end
+ end
+end
+
+class Sine < Expr
+ attr_accessor :argument
+
+ def initialize(argument)
+ @argument = argument
+ end
+
+ def self.build(operand)
+ a = Expr.build operand
+ new a
+ end
+
+ def evaluate(environment)
+ Math.sin(@argument.evaluate environment)
+ end
+
+ def derive(variable)
+ first = Cosine.new argument.derive variable
+ second = (Variable.new variable).derive variable
+ result = first * second
+ result.simplify
+ end
+
+ def simplify
+ if @argument.exact? then @argument.simplify
+ elsif @argument.number == 0 then Number.new 0
+ elsif @argument.number == 90 then Number.new 1
+ end
+ end
+
+ def exact?
+ @argument.exact?
+ end
+
+ def ==(other)
+ if other.instance_of? Sine
+ @argument == other.argument
+ else
+ false
+ end
+ end
+end
+
+class Cosine < Expr
+ attr_accessor :argument
+
+ def initialize(argument)
+ @argument = argument
+ end
+
+ def self.build(operand)
+ a = Expr.build operand
+ new a
+ end
+
+ def evaluate(environment)
+ Math.cos(@argument.evaluate environment)
+ end
+
+ def derive(variable)
+ first = Sine.new argument.derive variable
+ second = (Variable.new variable).derive variable
+ result = first * - second
+ result.simplify
+ end
+
+ def simplify
+ if @argument.exact? then @argument.simplify
+ elsif @argument.number == 0 then Number.new 1
+ elsif @argument.number == 90 then Number.new 0
+ end
+ end
+
+ def exact?
+ @argument.exact?
+ end
+
+ def ==(other)
+ if other.instance_of? Cosine
+ @argument == other.argument
+ else
+ false
+ end
+ end
+end
+
+class Addition < Expr
+ attr_accessor :addend_1, :addend_2
+
+ def initialize(operand_1,operand_2)
+ @addend_1 = operand_1
+ @addend_2 = operand_2
+ end
+
+ def self.build(operand_1,operand_2)
+ a = Expr.build operand_1
+ b = Expr.build operand_2
+ new a,b
+ end
+
+ def derive(variable)
+ first = addend_1.derive variable
+ second = addend_2.derive variable
+ result = first + second
+ result.simplify
+ end
+
+ def simplify
+ if @addend_1.instance_of? Number and @addend_2.instance_of? Number then
+ Number.new @addend_1.number + @addend_2.number
+ elsif @addend_1.instance_of? Number and @addend_1.number == 0 then @addend_2.simplify
+ elsif @addend_2.instance_of? Number and @addend_2.number == 0 then @addend_1.simplify
+ elsif @addend_1.exact? then @addend_1.simplify + @addend_2
+ elsif @addend_2.exact? then @addend_1 + @addend_2.simplify
+ elsif @addend_1.exact? then @addend_1.simplify + @addend_2.simplify
+ end
+ end
+
+ def exact?
+ @addend_1.exact? or @addend_2.exact?
+ end
+
+ def evaluate(environment)
+ first = @addend_1.evaluate environment
+ second = @addend_2.evaluate environment
+ first + second
+ end
+
+ def ==(other)
+ if other.instance_of? Addition
+ @addend_1 == other.addend_1 and @addend_2 == other.addend_2
+ else
+ false
+ end
+ end
+end
+
+class Multiplication < Expr
+ attr_accessor :multiplicand, :multiplier
+
+ def initialize(operand_1,operand_2)
+ @multiplicand = operand_1
+ @multiplier = operand_2
+ end
+
+ def self.build(operand_1,operand_2)
+ a = Expr.build operand_1
+ b = Expr.build operand_2
+ new a,b
+ end
+
+ def derive(variable)
+ first = multiplicand.derive variable
+ second = multiplier.derive variable
+ derived_1 = Multiplication.new first, multiplier
+ derived_2 = Multiplication.new multiplicand, second
+ result = derived_1 + derived_2
+ result.simplify
+ end
+
+ def simplify
+ unless @multiplicand.exact?
+ if @multiplicand.number == 0 then @multiplicand.simplify
+ elsif @multiplicand.number == 1 then @multiplier.simplify
+ elsif @multiplicand.instance_of? Number then @multiplier.simplify
+ end
+ else
+ if @multiplier.exact? then @multiplicand.simplify * @multilier.simplify
+ elsif @multiplier.number == 0 then @multiplier.simplify
+ elsif @multiplier.number == 1 then @multiplicand.simplify
+ elsif @multiplier.instance_of? Number then @multiplicand.simplify
+ end
+ end
+ end
+
+ def exact?
+ @multiplicand.exact? or @multiplier.exact?
+ end
+
+ def evaluate(environment)
+ first = @multiplicand.evaluate environment
+ second = @multiplier.evaluate environment
+ first * second
+ end
+
+ def ==(other)
+ if other.instance_of? Multiplication
+ @multiplicand == other.multiplicand and @multiplier == other.multiplier
+ else
+ false
+ end
+ end
+end