Решение на Трета задача от Никола Таушанов

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

Към профила на Никола Таушанов

Резултати

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

Код

class Expr
def self.build(tree)
if tree.kind_of? Array
case tree.first
when :+ then Addition.new Expr.build(tree[1]), Expr.build(tree[2])
when :* then Multiplication.new Expr.build(tree[1]), Expr.build(tree[2])
when :- then Negation.new Expr.build(tree[1])
when :sin then Sine.new Expr.build(tree[1])
when :cos then Cosine.new Expr.build(tree[1])
when :number then Number.new Expr.build(tree[1])
when :variable then Variable.new Expr.build(tree[1])
end
else
tree
end
end
def *(expr)
Multiplication.new(self, expr).simplify
end
def +(expr)
Addition.new(self, expr).simplify
end
def -@
Negation.new(self).simplify
end
def simplify
if exact? then Number.new(evaluate) else self end
end
alias eql? ==
end
class Unary < Expr
def initialize(operand)
@operand = operand
end
def exact?
@operand.exact?
end
def ==(expr)
self.class == expr.class and
expr.operand? @operand
end
def operand?(expr)
@operand == expr
end
end
class Binary < Expr
def initialize(left_operand, right_operand)
@left_operand, @right_operand = left_operand, right_operand
end
def exact?
@left_operand.exact? and @right_operand.exact?
end
def ==(expr)
self.class == expr.class and
expr.left_operand? @left_operand and
expr.right_operand? @right_operand
end
def left_operand?(expr)
@left_operand == expr
end
def right_operand?(expr)
@right_operand == expr
end
end
class Number < Unary
def evaluate(hash = {})
@operand
end
def derive(x)
Number.new(0)
end
def exact?
true
end
# def to_s
# @operand
# end
end
class Variable < Unary
def evaluate(hash = {})
hash[@operand]
end
def derive(x)
@operand == x ? Number.new(1) : Number.new(0)
end
def exact?
false
end
# def to_s
# @operand
# end
end
class Negation < Unary
def evaluate(hash = {})
-@operand.evaluate(hash)
end
def derive(x)
-@operand.derive(x)
end
# def to_s
# "-#{@operand.to_s}"
# end
end
class Sine < Unary
def evaluate(hash = {})
Math.sin @operand.evaluate(hash)
end
def derive
@operand.derive(x) * Cosine.new(@operand)
end
# def to_s
# "sin(#{@operand.to_s})"
# end
end
class Cosine < Unary
def evaluate(hash = {})
Math.cos @operand.evaluate(hash)
end
def derive(x)
@operand.derive(x) * -Sine.new(@operand)
end
# def to_s
# "cos(#{@operand.to_s})"
# end
end
class Addition < Binary
def evaluate(hash = {})
@left_operand.evaluate(hash) + @right_operand.evaluate(hash)
end
def derive(x)
@left_operand.derive(x) + @right_operand.derive(x)
end
def simplify
return super if exact?
left_simplified, right_simlified = @left_operand.simplify, @right_operand.simplify
if left_simplified == Number.new(0)
right_simlified
elsif right_simlified == Number.new(0)
left_simplified
else
Addition.new left_simplified, right_simlified
end
end
# def to_s
# "(#{@left_operand.to_s} + #{@right_operand.to_s})"
# end
end
class Multiplication < Binary
def evaluate(hash = {})
@left_operand.evaluate(hash) * @right_operand.evaluate(hash)
end
def derive(x)
@left_operand.derive(x) * @right_operand + @left_operand * @right_operand.derive(x)
end
def simplify
return super if exact?
left_simplified, right_simlified = @left_operand.simplify, @right_operand.simplify
if left_simplified == Number.new(0) or right_simlified == Number.new(0)
Number.new(0)
elsif left_simplified == Number.new(1)
right_simlified
elsif right_simlified == Number.new(1)
left_simplified
else
Multiplication.new left_simplified, right_simlified
end
end
# def to_s
# "(#{@left_operand.to_s} * #{@right_operand.to_s})"
# end
end

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

.............

Finished in 0.24955 seconds
13 examples, 0 failures

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

Никола обнови решението на 10.11.2012 03:00 (преди около 12 години)

+
+class Expr
+ def self.build(tree)
+ if tree.kind_of? Array
+ case tree.first
+ when :+ then Addition.new Expr.build(tree[1]), Expr.build(tree[2])
+ when :* then Multiplication.new Expr.build(tree[1]), Expr.build(tree[2])
+ when :- then Negation.new Expr.build(tree[1])
+ when :sin then Sine.new Expr.build(tree[1])
+ when :cos then Cosine.new Expr.build(tree[1])
+ when :number then Number.new Expr.build(tree[1])
+ when :variable then Variable.new Expr.build(tree[1])
+ end
+ else
+ tree
+ end
+ end
+
+ def *(expr)
+ Multiplication.new(self, expr).simplify
+ end
+
+ def +(expr)
+ Addition.new(self, expr).simplify
+ end
+
+ def -
+ Negation.new(self).simplify
+ end
+
+ def simplify
+ if exact? then Number.new(evaluate) else self end
+ end
+
+ alias eql? ==
+end
+
+class Unary < Expr
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def exact?
+ @operand.exact?
+ end
+
+ def ==(expr)
+ self.class == expr.class and
+ expr.operand? @operand
+ end
+
+ def operand?(expr)
+ @operand == expr
+ end
+end
+
+class Binary < Expr
+ def initialize(left_operand, right_operand)
+ @left_operand, @right_operand = left_operand, right_operand
+ end
+
+ def exact?
+ @left_operand.exact? and @right_operand.exact?
+ end
+
+ def ==(expr)
+ self.class == expr.class and
+ expr.left_operand? @left_operand and
+ expr.right_operand? @right_operand
+ end
+
+ def left_operand?(expr)
+ @left_operand == expr
+ end
+
+ def right_operand?(expr)
+ @right_operand == expr
+ end
+end
+
+class Number < Unary
+ def evaluate(hash = {})
+ @operand
+ end
+
+ def derive(x)
+ Number.new(0)
+ end
+
+ def exact?
+ true
+ end
+
+ # def to_s
+ # @operand
+ # end
+end
+
+class Variable < Unary
+ def evaluate(hash = {})
+ hash[@operand]
+ end
+
+ def derive(x)
+ @operand == x ? Number.new(1) : Number.new(0)
+ end
+
+ def exact?
+ false
+ end
+
+ # def to_s
+ # @operand
+ # end
+end
+
+class Negation < Unary
+ def evaluate(hash = {})
+ -@operand.evaluate(hash)
+ end
+
+ def derive(x)
+ -@operand.derive(x)
+ end
+
+ # def to_s
+ # "-#{@operand.to_s}"
+ # end
+end
+
+class Sine < Unary
+ def evaluate(hash = {})
+ Math.sin @operand.evaluate(hash)
+ end
+
+ def derive
+ @operand.derive(x) * Cosine.new(@operand)
+ end
+
+ # def to_s
+ # "sin(#{@operand.to_s})"
+ # end
+end
+
+class Cosine < Unary
+ def evaluate(hash = {})
+ Math.cos @operand.evaluate(hash)
+ end
+
+ def derive(x)
+ @operand.derive(x) * -Sine.new(@operand)
+ end
+
+ # def to_s
+ # "cos(#{@operand.to_s})"
+ # end
+end
+
+# Binary s-expressions
+class Addition < Binary
+ def evaluate(hash = {})
+ @left_operand.evaluate(hash) + @right_operand.evaluate(hash)
+ end
+
+ def derive(x)
+ @left_operand.derive(x) + @right_operand.derive(x)
+ end
+
+ def simplify
+ return super if exact?
+
+ left_simplified, right_simlified = @left_operand.simplify, @right_operand.simplify
+
+ if left_simplified == Number.new(0)
+ right_simlified
+ elsif right_simlified == Number.new(0)
+ left_simplified
+ else
+ Addition.new left_simplified, right_simlified
+ end
+ end
+
+ # def to_s
+ # "(#{@left_operand.to_s} + #{@right_operand.to_s})"
+ # end
+end
+
+class Multiplication < Binary
+ def evaluate(hash = {})
+ @left_operand.evaluate(hash) * @right_operand.evaluate(hash)
+ end
+
+ def derive(x)
+ @left_operand.derive(x) * @right_operand + @left_operand * @right_operand.derive(x)
+ end
+
+ def simplify
+ return super if exact?
+
+ left_simplified, right_simlified = @left_operand.simplify, @right_operand.simplify
+
+ if left_simplified == Number.new(0) or right_simlified == Number.new(0)
+ Number.new(0)
+ elsif left_simplified == Number.new(1)
+ right_simlified
+ elsif right_simlified == Number.new(1)
+ left_simplified
+ else
+ Multiplication.new left_simplified, right_simlified
+ end
+ end
+
+ # def to_s
+ # "(#{@left_operand.to_s} * #{@right_operand.to_s})"
+ # end
+end

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

class Expr
def self.build(tree)
if tree.kind_of? Array
case tree.first
when :+ then Addition.new Expr.build(tree[1]), Expr.build(tree[2])
when :* then Multiplication.new Expr.build(tree[1]), Expr.build(tree[2])
when :- then Negation.new Expr.build(tree[1])
when :sin then Sine.new Expr.build(tree[1])
when :cos then Cosine.new Expr.build(tree[1])
when :number then Number.new Expr.build(tree[1])
when :variable then Variable.new Expr.build(tree[1])
end
else
tree
end
end
def *(expr)
Multiplication.new(self, expr).simplify
end
def +(expr)
Addition.new(self, expr).simplify
end
- def -
+ def -@
Negation.new(self).simplify
end
def simplify
if exact? then Number.new(evaluate) else self end
end
alias eql? ==
end
class Unary < Expr
def initialize(operand)
@operand = operand
end
def exact?
@operand.exact?
end
def ==(expr)
self.class == expr.class and
expr.operand? @operand
end
def operand?(expr)
@operand == expr
end
end
class Binary < Expr
def initialize(left_operand, right_operand)
@left_operand, @right_operand = left_operand, right_operand
end
def exact?
@left_operand.exact? and @right_operand.exact?
end
def ==(expr)
self.class == expr.class and
expr.left_operand? @left_operand and
expr.right_operand? @right_operand
end
def left_operand?(expr)
@left_operand == expr
end
def right_operand?(expr)
@right_operand == expr
end
end
class Number < Unary
def evaluate(hash = {})
@operand
end
def derive(x)
Number.new(0)
end
def exact?
true
end
# def to_s
# @operand
# end
end
class Variable < Unary
def evaluate(hash = {})
hash[@operand]
end
def derive(x)
@operand == x ? Number.new(1) : Number.new(0)
end
def exact?
false
end
# def to_s
# @operand
# end
end
class Negation < Unary
def evaluate(hash = {})
-@operand.evaluate(hash)
end
def derive(x)
-@operand.derive(x)
end
# def to_s
# "-#{@operand.to_s}"
# end
end
class Sine < Unary
def evaluate(hash = {})
Math.sin @operand.evaluate(hash)
end
def derive
@operand.derive(x) * Cosine.new(@operand)
end
# def to_s
# "sin(#{@operand.to_s})"
# end
end
class Cosine < Unary
def evaluate(hash = {})
Math.cos @operand.evaluate(hash)
end
def derive(x)
@operand.derive(x) * -Sine.new(@operand)
end
# def to_s
# "cos(#{@operand.to_s})"
# end
end
-# Binary s-expressions
class Addition < Binary
def evaluate(hash = {})
@left_operand.evaluate(hash) + @right_operand.evaluate(hash)
end
def derive(x)
@left_operand.derive(x) + @right_operand.derive(x)
end
def simplify
return super if exact?
left_simplified, right_simlified = @left_operand.simplify, @right_operand.simplify
if left_simplified == Number.new(0)
right_simlified
elsif right_simlified == Number.new(0)
left_simplified
else
Addition.new left_simplified, right_simlified
end
end
# def to_s
# "(#{@left_operand.to_s} + #{@right_operand.to_s})"
# end
end
class Multiplication < Binary
def evaluate(hash = {})
@left_operand.evaluate(hash) * @right_operand.evaluate(hash)
end
def derive(x)
@left_operand.derive(x) * @right_operand + @left_operand * @right_operand.derive(x)
end
def simplify
return super if exact?
left_simplified, right_simlified = @left_operand.simplify, @right_operand.simplify
if left_simplified == Number.new(0) or right_simlified == Number.new(0)
Number.new(0)
elsif left_simplified == Number.new(1)
right_simlified
elsif right_simlified == Number.new(1)
left_simplified
else
Multiplication.new left_simplified, right_simlified
end
end
# def to_s
# "(#{@left_operand.to_s} * #{@right_operand.to_s})"
# end
end