Решение на Трета задача от Валентин Ейткен

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

Към профила на Валентин Ейткен

Резултати

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

Код

#!/usr/bin/env ruby
class Expr
def self.build(sexpression)
if sexpression.length == 2
Unary.build(sexpression)
elsif sexpression.length == 3
Binary.build(sexpression)
end
end
def initialize(sexpression)
@sexpression = sexpression
end
def ==(other)
@sexpression == other.sexpression
end
end
class Unary < Expr
attr_reader :operation, :argument
def self.build(expr_tree)
case expr_tree[0]
when :-
Negation.new([expr_tree[0], Expr.build(expr_tree[1])])
when :sin
Sine.new([expr_tree[0], Expr.build(expr_tree[1])])
when :cos
Cosine.new([expr_tree[0], Expr.build(expr_tree[1])])
when :variable
Variable.new([expr_tree[0], expr_tree[1]])
when :number
Number.new([expr_tree[0], expr_tree[1]])
end
end
def initialize(sexpression)
@sexpression = sexpression
@operation, @argument = sexpression
end
def ==(expr)
expr.operation == @operation and
expr.argument == @argument
end
private
def exact?
not @sexpression.flatten.include?(:variable)
end
def operands
[self]
end
end
class Binary < Expr
attr_reader :operation, :left_operand, :right_operand
def self.build(expr_tree)
Binary.new(expr_tree[0], Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
end
def initialize(*expr_tree)
@operation, @left_operand, @right_operand = expr_tree[0], expr_tree[1], expr_tree[2]
end
def evaluate(environment = {})
@left_operand.evaluate(environment).send(@operation, @right_operand.evaluate(environment))
end
def ==(expr)
expr.operation == @operation and
expr.left_operand == @left_operand and expr.right_operand == @right_operand
end
def simplify
if @left_operand.exact? and @right_operand.exact?
[:number, evaluate]
elsif @left_operand.exact?
@left_operand.operands.product(@right_operand.operands).each do |binary_elements|
##
end
else
[@operation, @left_operand.simplify, @right_operand.simplify]
end
end
private
def operands
[@left_operand, @right_operand]
end
def exact?
@left_operand.exact? and @right_operand.exact?
end
end
class Number < Unary
def evaluate(environment = {})
@argument
end
def simplify
@sexpression
end
def exact?
true
end
end
class Variable < Unary
def evaluate(environment = {})
environment[@argument]
end
def simplify
@sexpression
end
def exact?
false
end
end
class Negation < Unary
def evaluate(environment = {})
-(@argument.evaluate(environment))
end
def simplify
if exact?
[:-, evaluate]
else
@sexpression
end
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin(@argument.evaluate(environment))
end
def simplify
if exact?
[:sin, evaluate]
else
@sexpression
end
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@argument.evaluate(environment))
end
def simplify
if exact?
[:cos, evaluate]
else
@sexpression
end
end
end

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

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

Failures:

  1) Expressions assignment supports simplification
     Failure/Error: simplify('x + 0').should eq build('x')
       
       expected: #<Variable:0x9eddf38 @sexpression=[:variable, :x], @operation=:variable, @argument=:x>
            got: [:+, [:variable, :x], [:number, 0]]
       
       (compared using ==)
     # /tmp/d20130203-23049-1ptacat/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 #<Variable:0x9d9faf4>
     # /tmp/d20130203-23049-1ptacat/spec.rb:129:in `derive'
     # /tmp/d20130203-23049-1ptacat/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.04969 seconds
13 examples, 2 failures

Failed examples:

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

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

Валентин обнови решението на 12.11.2012 02:21 (преди около 12 години)

+class Expr
+ def self.build(sexpression)
+ if sexpression.length == 2
+ Unary.build(sexpression)
+ elsif sexpression.length == 3
+ Binary.build(sexpression)
+ end
+ end
+
+ def initialize(sexpression)
+ @sexpression = sexpression
+ end
+
+ def ==(other)
+ @sexpression == other.sexpression
+ end
+
+ def evaluate(expression = {})
+ end
+end
+
+
+class Unary < Expr
+ attr_reader :operation, :argument
+
+ def initialize(operation, argument)
+ @operation, @argument = operation, argument
+ end
+
+ def self.build(expr_tree)
+ case expr_tree[0]
+ when :-
+ Negation.new(expr_tree[0], Expr.build(expr_tree[1]))
+ when :sin
+ Sine.new(expr_tree[0], Expr.build(expr_tree[1]))
+ when :cos
+ Cosine.new(expr_tree[0], Expr.build(expr_tree[1]))
+ when :variable
+ Variable.new(expr_tree[0], expr_tree[1])
+ when :number
+ Number.new(expr_tree[0], expr_tree[1])
+ end
+ end
+
+ def ==(expr)
+ expr.operation == @operation and
+ expr.argument == @argument
+ end
+end
+
+
+class Binary < Expr
+ attr_reader :operation, :left_operand, :right_operand
+
+ def self.build(expr_tree)
+ Binary.new(expr_tree[0], Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
+ end
+
+ def initialize(*expr_tree)
+ @operation, @left_operand, @right_operand = expr_tree[0], expr_tree[1], expr_tree[2]
+ end
+
+ def evaluate(environment = {})
+ @left_operand.evaluate(environment).send(@operation, @right_operand.evaluate(environment))
+ end
+
+ def ==(expr)
+ expr.operation == @operation and
+ expr.left_operand == @left_operand and expr.right_operand == @right_operand
+ end
+end
+
+
+class Number < Unary
+ def evaluate(environment = {})
+ @argument
+ end
+end
+
+
+class Negation < Unary
+ def evaluate(environment = {})
+ -(@argument.evaluate(environment))
+ end
+end
+
+
+class Variable < Unary
+ def evaluate(environment = {})
+ environment[@argument]
+ end
+end
+
+
+class Sine < Unary
+ def evaluate(environment = {})
+ Math.sin(@argument.evaluate(environment))
+ end
+end
+
+
+class Cosine < Unary
+ def evaluate(environment = {})
+ Math.cos(@argument.evaluate(environment))
+ end
+end

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

+#!/usr/bin/env ruby
+
class Expr
def self.build(sexpression)
if sexpression.length == 2
Unary.build(sexpression)
elsif sexpression.length == 3
Binary.build(sexpression)
end
end
def initialize(sexpression)
@sexpression = sexpression
end
def ==(other)
@sexpression == other.sexpression
end
-
- def evaluate(expression = {})
- end
end
class Unary < Expr
attr_reader :operation, :argument
- def initialize(operation, argument)
- @operation, @argument = operation, argument
- end
-
def self.build(expr_tree)
case expr_tree[0]
when :-
- Negation.new(expr_tree[0], Expr.build(expr_tree[1]))
+ Negation.new([expr_tree[0], Expr.build(expr_tree[1])])
when :sin
- Sine.new(expr_tree[0], Expr.build(expr_tree[1]))
+ Sine.new([expr_tree[0], Expr.build(expr_tree[1])])
when :cos
- Cosine.new(expr_tree[0], Expr.build(expr_tree[1]))
+ Cosine.new([expr_tree[0], Expr.build(expr_tree[1])])
when :variable
- Variable.new(expr_tree[0], expr_tree[1])
+ Variable.new([expr_tree[0], expr_tree[1]])
when :number
- Number.new(expr_tree[0], expr_tree[1])
+ Number.new([expr_tree[0], expr_tree[1]])
end
end
+ def initialize(sexpression)
+ @sexpression = sexpression
+ @operation, @argument = sexpression
+ end
+
def ==(expr)
expr.operation == @operation and
expr.argument == @argument
end
+
+ private
+ def exact?
+ not @sexpression.flatten.include?(:variable)
+ end
+
+ def operands
+ [self]
+ end
end
class Binary < Expr
attr_reader :operation, :left_operand, :right_operand
-
def self.build(expr_tree)
Binary.new(expr_tree[0], Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
end
def initialize(*expr_tree)
@operation, @left_operand, @right_operand = expr_tree[0], expr_tree[1], expr_tree[2]
end
def evaluate(environment = {})
@left_operand.evaluate(environment).send(@operation, @right_operand.evaluate(environment))
end
def ==(expr)
expr.operation == @operation and
expr.left_operand == @left_operand and expr.right_operand == @right_operand
end
+
+ def simplify
+ if @left_operand.exact? and @right_operand.exact?
+ [:number, evaluate]
+ elsif @left_operand.exact?
+ @left_operand.operands.product(@right_operand.operands).each do |binary_elements|
+##
+ end
+ else
+ [@operation, @left_operand.simplify, @right_operand.simplify]
+ end
+ end
+
+ private
+ def operands
+ [@left_operand, @right_operand]
+ end
+
+ def exact?
+ @left_operand.exact? and @right_operand.exact?
+ end
end
class Number < Unary
def evaluate(environment = {})
@argument
end
-end
+ def simplify
+ @sexpression
+ end
-class Negation < Unary
- def evaluate(environment = {})
- -(@argument.evaluate(environment))
+ def exact?
+ true
end
end
class Variable < Unary
def evaluate(environment = {})
environment[@argument]
end
+
+ def simplify
+ @sexpression
+ end
+
+ def exact?
+ false
+ end
end
+class Negation < Unary
+ def evaluate(environment = {})
+ -(@argument.evaluate(environment))
+ end
+
+ def simplify
+ if exact?
+ [:-, evaluate]
+ else
+ @sexpression
+ end
+ end
+end
+
+
class Sine < Unary
def evaluate(environment = {})
Math.sin(@argument.evaluate(environment))
end
+
+ def simplify
+ if exact?
+ [:sin, evaluate]
+ else
+ @sexpression
+ end
+ end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos(@argument.evaluate(environment))
+ end
+
+ def simplify
+ if exact?
+ [:cos, evaluate]
+ else
+ @sexpression
+ end
end
end