Решение на Трета задача от Дамяна Иванова

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

Към профила на Дамяна Иванова

Резултати

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

Код

class Unary
attr_accessor :expr
def initialize(expr)
@expr = expr
end
def evaluate(env = {})
case expr[0]
when :-
Negation.new(expr[1]).evaluate(env)
when :sin
Sine.new(expr[1]).evaluate(env)
when :cos
Cosine.new(expr[1]).evaluate(env)
end
end
end
class Binary
attr_accessor :expr
def initialize(expr)
@expr = expr
end
def evaluate(env = {})
case expr[1]
when :+
Addition.new(expr[0], expr[2]).evaluate(env)
when :*
Multiplication.new(expr[0], expr[2]).evaluate(env)
end
end
end
class Number
def initialize(value)
@value = value
end
def evaluate(env = {})
@value
end
end
class Variable
def initialize(variable)
@variable = variable
end
def evaluate(env = {})
env[@variable]
end
end
class Addition
def initialize(left, right)
@left = left.is_a?(Numeric) ? Number.new(left) : Variable.new(left)
@right = right.is_a?(Numeric) ? Number.new(right) : Variable.new(right)
end
def evaluate(env = {})
@left.evaluate(env) + @right.evaluate(env)
end
end
class Multiplication
def initialize(left, right)
@left = left.is_a?(Numeric) ? Number.new(left) : Variable.new(left)
@right = right.is_a?(Numeric) ? Number.new(right) : Variable.new(right)
end
def evaluate(env = {})
@left.evaluate(env) * @right.evaluate(env)
end
end
class Negation
def initialize(operant)
@operant = operant.is_a?(Numeric) ? Number.new(operant) : Variable.new(operant)
end
def evaluate(env = {})
-@operant.evaluate(env)
end
end
class Sine
def initialize(operant)
@operant = operant.is_a?(Numeric) ? Number.new(operant) : Variable.new(operant)
end
def evaluate(env = {})
Math.sin(@operant.evaluate(env))
end
end
class Cosine
def initialize(operant)
@operant = operant.is_a?(Numeric) ? Number.new(operant) : Variable.new(operant)
end
def evaluate(env = {})
Math.cos(@operant.evaluate(env))
end
end
class Expr
attr_accessor :expr
def initialize(expr)
@expr = expr
end
def Expr.build(sexpr)
expr = Expr.create(sexpr).flatten(1)
Expr.new(expr)
end
def Expr.create(sexpr)
expr = []
case sexpr[0]
when :number then expr = [sexpr[1]]
when :variable then expr = [sexpr[1]]
when :+ then expr << (create(sexpr[2]).unshift(create(sexpr[1]) | [sexpr[0]])).flatten(1)
when :* then expr << (create(sexpr[2]).unshift(create(sexpr[1]) | [sexpr[0]])).flatten(1)
when :- then expr << ([sexpr[0]] | create(sexpr[1]))
when :sin then expr << ([sexpr[0]] | create(sexpr[1]))
when :cos then expr << ([sexpr[0]] | create(sexpr[1]))
end
end
def ==(other)
return self.expr == other.expr
end
def evaluate(env = {})
case expr.length
when 1
return expr[0]
when 2
operant = expr[1].is_a?(Array) ? Expr.new(expr[1]).evaluate(env) : expr[1]
return Unary.new([expr[0], operant]).evaluate(env)
when 3
left = expr[0].is_a?(Array) ? Expr.new(expr[0]).evaluate(env) : expr[0]
right = expr[2].is_a?(Array) ? Expr.new(expr[2]).evaluate(env) : expr[2]
return Binary.new([left, expr[1], right]).evaluate(env)
end
end
def exact?
case expr.length
when 1
return true
when 2
return expr[1].is_a?(Array) ? Expr.new(expr[1]).exact? : expr[1].is_a?(Numeric)
when 3
left = expr[0].is_a?(Array) ? Expr.new(expr[0]).exact? : expr[0].is_a?(Numeric)
right = expr[2].is_a?(Array) ? Expr.new(expr[2]).exact? : expr[2].is_a?(Numeric)
left and right
end
end
def simplify
evaluate if exact?
end
end

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

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

Failures:

  1) Expressions assignment supports simplification
     Failure/Error: simplify('x + 0').should eq build('x')
       
       expected: #<Expr:0x9a0c018 @expr=[:x]>
            got: nil
       
       (compared using ==)
     # /tmp/d20130203-23049-gbgl86/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: build(string).derive(:x)
     NoMethodError:
       undefined method `derive' for #<Expr:0x9b6c19c @expr=[:x]>
     # /tmp/d20130203-23049-gbgl86/spec.rb:129:in `derive'
     # /tmp/d20130203-23049-gbgl86/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.04033 seconds
13 examples, 2 failures

Failed examples:

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

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

Дамяна обнови решението на 14.11.2012 02:39 (преди над 11 години)

+class Unary
+ attr_accessor :expr
+
+ def initialize(expr)
+ @expr = expr
+ end
+
+ def evaluate(env = {})
+ case expr[0]
+ when :-
+ Negation.new(expr[1]).evaluate(env)
+ when :sin
+ Sine.new(expr[1]).evaluate(env)
+ when :cos
+ Cosine.new(expr[1]).evaluate(env)
+ end
+ end
+end
+
+class Binary
+ attr_accessor :expr
+
+ def initialize(expr)
+ @expr = expr
+ end
+
+ def evaluate(env = {})
+ case expr[1]
+ when :+
+ Addition.new(expr[0], expr[2]).evaluate(env)
+ when :*
+ Multiplication.new(expr[0], expr[2]).evaluate(env)
+ end
+ end
+end
+
+class Number
+ def initialize(value)
+ @value = value
+ end
+
+ def evaluate(env = {})
+ @value
+ end
+end
+
+class Variable
+ def initialize(variable)
+ @variable = variable
+ end
+
+ def evaluate(env = {})
+ env[@variable]
+ end
+end
+
+class Addition
+ def initialize(left, right)
+ @left = left.is_a?(Numeric) ? Number.new(left) : Variable.new(left)
+ @right = right.is_a?(Numeric) ? Number.new(right) : Variable.new(right)
+ end
+
+ def evaluate(env = {})
+ @left.evaluate(env) + @right.evaluate(env)
+ end
+end
+
+class Multiplication
+ def initialize(left, right)
+ @left = left.is_a?(Numeric) ? Number.new(left) : Variable.new(left)
+ @right = right.is_a?(Numeric) ? Number.new(right) : Variable.new(right)
+ end
+
+ def evaluate(env = {})
+ @left.evaluate(env) * @right.evaluate(env)
+ end
+end
+
+class Negation
+ def initialize(operant)
+ @operant = operant.is_a?(Numeric) ? Number.new(operant) : Variable.new(operant)
+ end
+
+ def evaluate(env = {})
+ -@operant.evaluate(env)
+ end
+end
+
+class Sine
+ def initialize(operant)
+ @operant = operant.is_a?(Numeric) ? Number.new(operant) : Variable.new(operant)
+ end
+
+ def evaluate(env = {})
+ Math.sin(@operant.evaluate(env))
+ end
+end
+
+class Cosine
+ def initialize(operant)
+ @operant = operant.is_a?(Numeric) ? Number.new(operant) : Variable.new(operant)
+ end
+
+ def evaluate(env = {})
+ Math.cos(@operant.evaluate(env))
+ end
+end
+
+class Expr
+ attr_accessor :expr
+
+ def initialize(expr)
+ @expr = expr
+ end
+
+ def Expr.build(sexpr)
+ expr = Expr.create(sexpr).flatten(1)
+ Expr.new(expr)
+ end
+
+ def Expr.create(sexpr)
+ expr = []
+ case sexpr[0]
+ when :number then expr = [sexpr[1]]
+ when :variable then expr = [sexpr[1]]
+ when :+ then expr << (create(sexpr[2]).unshift(create(sexpr[1]) | [sexpr[0]])).flatten(1)
+ when :* then expr << (create(sexpr[2]).unshift(create(sexpr[1]) | [sexpr[0]])).flatten(1)
+ when :- then expr << ([sexpr[0]] | create(sexpr[1]))
+ when :sin then expr << ([sexpr[0]] | create(sexpr[1]))
+ when :cos then expr << ([sexpr[0]] | create(sexpr[1]))
+ end
+ end
+
+ def ==(other)
+ return self.expr == other.expr
+ end
+
+ def evaluate(env = {})
+ case expr.length
+ when 1
+ return expr[0]
+ when 2
+ operant = expr[1].is_a?(Array) ? Expr.new(expr[1]).evaluate(env) : expr[1]
+ return Unary.new([expr[0], operant]).evaluate(env)
+ when 3
+ left = expr[0].is_a?(Array) ? Expr.new(expr[0]).evaluate(env) : expr[0]
+ right = expr[2].is_a?(Array) ? Expr.new(expr[2]).evaluate(env) : expr[2]
+ return Binary.new([left, expr[1], right]).evaluate(env)
+ end
+ end
+
+ def exact?
+ case expr.length
+ when 1
+ return true
+ when 2
+ return expr[1].is_a?(Array) ? Expr.new(expr[1]).exact? : expr[1].is_a?(Numeric)
+ when 3
+ left = expr[0].is_a?(Array) ? Expr.new(expr[0]).exact? : expr[0].is_a?(Numeric)
+ right = expr[2].is_a?(Array) ? Expr.new(expr[2]).exact? : expr[2].is_a?(Numeric)
+ left and right
+ end
+ end
+
+ def simplify
+ evaluate if exact?
+ end
+end