Решение на Трета задача от Гергана Петрова

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

Към профила на Гергана Петрова

Резултати

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

Код

class Expr
def Expr.build(expr_tree)
case expr_tree.first
when :number then Number.new(expr_tree[1])
when :variable then Variable.new(expr_tree[1])
when :+ then Addition.new(Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
when :* then Multiplication.new(Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
when :- then Negation.new(Expr.build(expr_tree[1]))
when :sin then Sine.new(Expr.build(expr_tree[1]))
when :cos then Cosine.new(Expr.build(expr_tree[1]))
end
end
def +(other_expr)
Addition.new(self, other_expr)
end
def *(other_expr)
Multiplication.new(self, other_expr)
end
def -@
Negation.new(self)
end
end
class Unary < Expr
attr_accessor :argument
def initialize(argument)
@argument = argument
end
def ==(other_expr)
@argument == other_expr.argument
end
end
class Binary < Expr
attr_accessor :arguments
def initialize(*arguments)
@arguments = arguments
end
def ==(other_expr)
@arguments == other_expr.arguments
end
def exact?
@arguments[0].exact? and @arguments[1].exact?
end
end
class Number < Unary
def evaluate(*_)
@argument
end
def derive(*_)
Number.new 0
end
def exact?
true
end
def simplify
self
end
end
class Variable < Unary
def evaluate(environment = {})
environment[@argument] or raise "Missing value for #{@argument} in environment"
end
def derive(variable)
@argument == variable ? Number.new(1) : Number.new(0)
end
def exact?
false
end
def simplify
self
end
end
class Addition < Binary
def evaluate(environment = {})
@arguments.map { |argument| argument.evaluate(environment) }.inject(:+)
end
def derive(variable)
@arguments.map { |argument| argument.derive(variable) }.inject(:+).simplify
end
def simplify
first_argument, second_argument = @arguments.map { |argument| argument.simplify }
if first_argument.exact? and second_argument.exact?
Number.new(first_argument.evaluate + second_argument.evaluate)
elsif first_argument.exact? and first_argument.evaluate == 0 then second_argument
elsif second_argument.exact? and second_argument.evaluate == 0 then first_argument
else self
end
end
end
class Multiplication < Binary
def evaluate(environment = {})
@arguments.map { |argument| argument.evaluate(environment) }.inject(:*)
end
def derive(variable)
first_addend = @arguments[0].derive(variable) * @arguments[1]
second_addend = @arguments[0] * @arguments[1].derive(variable)
first_addend.simplify + second_addend.simplify
end
def simplify
first_argument, second_argument = @arguments.map { |argument| argument.simplify }
if first_argument.exact? and second_argument.exact?
Number.new(first_argument.evaluate * second_argument.evaluate)
elsif first_argument.exact? and first_argument.evaluate == 0 then Number.new 0
elsif second_argument.exact? and second_argument.evaluate == 0 then Number.new 0
elsif first_argument.exact? and first_argument.evaluate == 1 then second_argument
elsif second_argument.exact? and second_argument.evaluate == 1 then first_argument
else self
end
end
end
class Negation < Unary
def evaluate(environment = {})
-@argument.evaluate(environment)
end
def derive(variable)
-@argument.derive(variable).simplify
end
def exact?
@argument.exact?
end
def simplify
@argument.simplify
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin @argument.evaluate(environment)
end
def derive(variable)
@argument.derive(variable) * Cosine.new(@argument)
end
def exact?
@argument.exact?
end
def simplify
argument = @argument.simplify
if argument.exact?
Math.sin argument.evaluate(environment)
else
Sine.new argument
end
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos @argument.evaluate(environment)
end
def derive(variable)
@argument.derive(variable) * - Sine.new(@argument)
end
def exact?
@argument.exact?
end
def simplify
argument = @argument.simplify
if argument.exact?
Math.cos argument.evaluate(environment)
else
Cosine.new argument
end
end
end

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

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

Finished in 0.05343 seconds
13 examples, 0 failures

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

Гергана обнови решението на 12.11.2012 01:21 (преди над 11 години)

+class Expr
+
+ def Expr.build(expr_tree)
+ case expr_tree.first
+ when :number then Number.new(expr_tree[1])
+ when :variable then Variable.new(expr_tree[1])
+ when :+ then Addition.new(Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
+ when :* then Multiplication.new(Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
+ when :- then Negation.new(Expr.build(expr_tree[1]))
+ when :sin then Sine.new(Expr.build(expr_tree[1]))
+ when :cos then Cosine.new(Expr.build(expr_tree[1]))
+ end
+ end
+
+ def +(other_expr)
+ Addition.new(self.simplify, other_expr.simplify)
+ end
+
+ def *(other_expr)
+ Multiplication.new(self.simplify, other_expr.simplify)
+ end
+
+ def -@
+ Negation.new(self.simplify)
+ end
+end
+
+class Unary < Expr
+ attr_accessor :argument
+
+ def initialize(argument)
+ @argument = argument
+ end
+
+ def ==(other_expr)
+ @argument == other_expr.argument
+ end
+end
+
+class Binary < Expr
+ attr_accessor :arguments
+
+ def initialize(*arguments)
+ @arguments = arguments
+ end
+
+ def ==(other_expr)
+ @arguments == other_expr.arguments
+ end
+
+ def exact?
+ @arguments[0].exact? and @arguments[1].exact?
+ end
+end
+
+class Number < Unary
+
+ def evaluate(*_)
+ @argument
+ end
+
+ def derive(*_)
+ 0
+ end
+
+ def exact?
+ true
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Variable < Unary
+
+ def evaluate(environment = {})
+ environment[@argument] or raise "Missing value for #{@argument} in environment"
+ end
+
+ def derive(variable)
+ @argument == variable ? Number.new(1) : Number.new(0)
+ end
+
+ def exact?
+ false
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Addition < Binary
+
+ def evaluate(environment = {})
+ @arguments.map { |argument| argument.evaluate(environment) }.inject(:+)
+ end
+
+ def derive(variable)
+ @arguments.map { |argument| argument.derive(variable) }.inject(:+).simplify
+ end
+
+ def simplify
+ first_argument, second_argument = @arguments.map { |argument| argument.simplify }
+ if first_argument.exact? and second_argument.exact?
+ Number.new(first_argument.evaluate + second_argument.evaluate)
+ elsif first_argument.exact? and first_argument.evaluate == 0 then second_argument
+ elsif second_argument.exact? and second_argument.evaluate == 0 then first_argument
+ else self
+ end
+ end
+end
+
+class Multiplication < Binary
+
+ def evaluate(environment = {})
+ @arguments.map { |argument| argument.evaluate(environment) }.inject(:*)
+ end
+
+ def derive(variable)
+ first_addend = @arguments[0].derive(variable) * @arguments[1]
+ second_addend = @arguments[0] * @arguments[1].derive(variable)
+ first_addend.simplify + second_addend.simplify
+ end
+
+ def simplify
+ first_argument, second_argument = @arguments.map { |argument| argument.simplify }
+ if first_argument.exact? and second_argument.exact?
+ Number.new(first_argument.evaluate * second_argument.evaluate)
+ elsif first_argument.exact? and first_argument.evaluate == 0 then Number.new 0
+ elsif second_argument.exact? and second_argument.evaluate == 0 then Number.new 0
+ elsif first_argument.exact? and first_argument.evaluate == 1 then second_argument
+ elsif second_argument.exact? and second_argument.evaluate == 1 then first_argument
+ else self
+ end
+ end
+end
+
+class Negation < Unary
+
+ def evaluate(environment = {})
+ -@argument.evaluate(environment)
+ end
+
+ def derive(variable)
+ -@argument.derive(variable).simplify
+ end
+
+ def exact?
+ @argument.exact?
+ end
+
+ def simplify
+ @argument.simplify
+ end
+end
+
+class Sine < Unary
+
+ def evaluate(environment = {})
+ Math.sin @argument.evaluate(environment)
+ end
+
+ def derive(variable)
+ @argument.derive(variable) * Math.cos(@argument).simplify
+ end
+
+ def exact?
+ @argument.exact?
+ end
+
+ def simplify
+ argument = @argument.simplify
+ if argument.exact?
+ Math.sin argument.evaluate
+ else
+ Sine.new argument
+ end
+ end
+end
+
+class Cosine < Unary
+
+ def evaluate(environment = {})
+ Math.cos @argument.evaluate(environment)
+ end
+
+ def derive(variable)
+ @argument.derive(variable) * - Math.sin(@argument)
+ end
+
+ def exact?
+ @argument.exact?
+ end
+
+ def simplify
+ argument = @argument.simplify
+ if argument.exact?
+ Math.cos argument.evaluate
+ else
+ Cosine.new argument
+ end
+ end
+end

Гергана обнови решението на 12.11.2012 16:44 (преди над 11 години)

class Expr
def Expr.build(expr_tree)
case expr_tree.first
when :number then Number.new(expr_tree[1])
when :variable then Variable.new(expr_tree[1])
when :+ then Addition.new(Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
when :* then Multiplication.new(Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
when :- then Negation.new(Expr.build(expr_tree[1]))
when :sin then Sine.new(Expr.build(expr_tree[1]))
when :cos then Cosine.new(Expr.build(expr_tree[1]))
end
end
def +(other_expr)
Addition.new(self.simplify, other_expr.simplify)
end
def *(other_expr)
Multiplication.new(self.simplify, other_expr.simplify)
end
def -@
Negation.new(self.simplify)
end
end
class Unary < Expr
attr_accessor :argument
def initialize(argument)
@argument = argument
end
def ==(other_expr)
@argument == other_expr.argument
end
end
class Binary < Expr
attr_accessor :arguments
def initialize(*arguments)
@arguments = arguments
end
def ==(other_expr)
@arguments == other_expr.arguments
end
def exact?
@arguments[0].exact? and @arguments[1].exact?
end
end
class Number < Unary
def evaluate(*_)
@argument
end
def derive(*_)
- 0
+ Number.new 0
end
def exact?
true
end
def simplify
self
end
end
class Variable < Unary
def evaluate(environment = {})
environment[@argument] or raise "Missing value for #{@argument} in environment"
end
def derive(variable)
@argument == variable ? Number.new(1) : Number.new(0)
end
def exact?
false
end
def simplify
self
end
end
class Addition < Binary
def evaluate(environment = {})
@arguments.map { |argument| argument.evaluate(environment) }.inject(:+)
end
def derive(variable)
@arguments.map { |argument| argument.derive(variable) }.inject(:+).simplify
end
def simplify
first_argument, second_argument = @arguments.map { |argument| argument.simplify }
if first_argument.exact? and second_argument.exact?
Number.new(first_argument.evaluate + second_argument.evaluate)
elsif first_argument.exact? and first_argument.evaluate == 0 then second_argument
elsif second_argument.exact? and second_argument.evaluate == 0 then first_argument
else self
end
end
end
class Multiplication < Binary
def evaluate(environment = {})
@arguments.map { |argument| argument.evaluate(environment) }.inject(:*)
end
def derive(variable)
first_addend = @arguments[0].derive(variable) * @arguments[1]
second_addend = @arguments[0] * @arguments[1].derive(variable)
first_addend.simplify + second_addend.simplify
end
def simplify
first_argument, second_argument = @arguments.map { |argument| argument.simplify }
if first_argument.exact? and second_argument.exact?
Number.new(first_argument.evaluate * second_argument.evaluate)
elsif first_argument.exact? and first_argument.evaluate == 0 then Number.new 0
elsif second_argument.exact? and second_argument.evaluate == 0 then Number.new 0
elsif first_argument.exact? and first_argument.evaluate == 1 then second_argument
elsif second_argument.exact? and second_argument.evaluate == 1 then first_argument
else self
end
end
end
class Negation < Unary
def evaluate(environment = {})
-@argument.evaluate(environment)
end
def derive(variable)
-@argument.derive(variable).simplify
end
def exact?
@argument.exact?
end
def simplify
@argument.simplify
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin @argument.evaluate(environment)
end
def derive(variable)
- @argument.derive(variable) * Math.cos(@argument).simplify
+ @argument.derive(variable) * Cosine.new(@argument)
end
def exact?
@argument.exact?
end
def simplify
argument = @argument.simplify
if argument.exact?
- Math.sin argument.evaluate
+ Math.sin argument.evaluate(environment)
else
Sine.new argument
end
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos @argument.evaluate(environment)
end
def derive(variable)
- @argument.derive(variable) * - Math.sin(@argument)
+ @argument.derive(variable) * - Sine.new(@argument)
end
def exact?
@argument.exact?
end
def simplify
argument = @argument.simplify
if argument.exact?
- Math.cos argument.evaluate
+ Math.cos argument.evaluate(environment)
else
Cosine.new argument
end
end
end

Гергана обнови решението на 12.11.2012 22:28 (преди над 11 години)

class Expr
def Expr.build(expr_tree)
case expr_tree.first
when :number then Number.new(expr_tree[1])
when :variable then Variable.new(expr_tree[1])
when :+ then Addition.new(Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
when :* then Multiplication.new(Expr.build(expr_tree[1]), Expr.build(expr_tree[2]))
when :- then Negation.new(Expr.build(expr_tree[1]))
when :sin then Sine.new(Expr.build(expr_tree[1]))
when :cos then Cosine.new(Expr.build(expr_tree[1]))
end
end
def +(other_expr)
- Addition.new(self.simplify, other_expr.simplify)
+ Addition.new(self, other_expr)
end
def *(other_expr)
- Multiplication.new(self.simplify, other_expr.simplify)
+ Multiplication.new(self, other_expr)
end
def -@
- Negation.new(self.simplify)
+ Negation.new(self)
end
end
class Unary < Expr
attr_accessor :argument
def initialize(argument)
@argument = argument
end
def ==(other_expr)
@argument == other_expr.argument
end
end
class Binary < Expr
attr_accessor :arguments
def initialize(*arguments)
@arguments = arguments
end
def ==(other_expr)
@arguments == other_expr.arguments
end
def exact?
@arguments[0].exact? and @arguments[1].exact?
end
end
class Number < Unary
def evaluate(*_)
@argument
end
def derive(*_)
Number.new 0
end
def exact?
true
end
def simplify
self
end
end
class Variable < Unary
def evaluate(environment = {})
environment[@argument] or raise "Missing value for #{@argument} in environment"
end
def derive(variable)
@argument == variable ? Number.new(1) : Number.new(0)
end
def exact?
false
end
def simplify
self
end
end
class Addition < Binary
def evaluate(environment = {})
@arguments.map { |argument| argument.evaluate(environment) }.inject(:+)
end
def derive(variable)
@arguments.map { |argument| argument.derive(variable) }.inject(:+).simplify
end
def simplify
first_argument, second_argument = @arguments.map { |argument| argument.simplify }
if first_argument.exact? and second_argument.exact?
Number.new(first_argument.evaluate + second_argument.evaluate)
elsif first_argument.exact? and first_argument.evaluate == 0 then second_argument
elsif second_argument.exact? and second_argument.evaluate == 0 then first_argument
else self
end
end
end
class Multiplication < Binary
def evaluate(environment = {})
@arguments.map { |argument| argument.evaluate(environment) }.inject(:*)
end
def derive(variable)
first_addend = @arguments[0].derive(variable) * @arguments[1]
second_addend = @arguments[0] * @arguments[1].derive(variable)
first_addend.simplify + second_addend.simplify
end
def simplify
first_argument, second_argument = @arguments.map { |argument| argument.simplify }
if first_argument.exact? and second_argument.exact?
Number.new(first_argument.evaluate * second_argument.evaluate)
elsif first_argument.exact? and first_argument.evaluate == 0 then Number.new 0
elsif second_argument.exact? and second_argument.evaluate == 0 then Number.new 0
elsif first_argument.exact? and first_argument.evaluate == 1 then second_argument
elsif second_argument.exact? and second_argument.evaluate == 1 then first_argument
else self
end
end
end
class Negation < Unary
def evaluate(environment = {})
-@argument.evaluate(environment)
end
def derive(variable)
-@argument.derive(variable).simplify
end
def exact?
@argument.exact?
end
def simplify
@argument.simplify
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin @argument.evaluate(environment)
end
def derive(variable)
@argument.derive(variable) * Cosine.new(@argument)
end
def exact?
@argument.exact?
end
def simplify
argument = @argument.simplify
if argument.exact?
Math.sin argument.evaluate(environment)
else
Sine.new argument
end
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos @argument.evaluate(environment)
end
def derive(variable)
@argument.derive(variable) * - Sine.new(@argument)
end
def exact?
@argument.exact?
end
def simplify
argument = @argument.simplify
if argument.exact?
Math.cos argument.evaluate(environment)
else
Cosine.new argument
end
end
end