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

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

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

Резултати

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

Код

class Expr
@@types = {}
def ==(other)
other.class == self.class and other.state == state
end
def self.build(s_expr)
type, *s_args = *s_expr
@@types[type].build(s_args)
end
def +(other)
Addition.new(self, other)
end
def *(other)
Multiplication.new(self, other)
end
def -@
Negation.new(self)
end
def simplify
self
end
end
class Atomic < Expr
attr_accessor :value
def initialize(value)
@value = value
end
def self.build(value)
new value.first
end
alias state value
end
class Number < Atomic
@@types[:number] = self
ZERO = self.new(0)
ONE = self.new(1)
def evaluate(environment = {})
value
end
def derive(variable)
ZERO
end
def exact?
true
end
end
class Variable < Atomic
@@types[:variable] = self
def evaluate(environment = {})
if environment.has_key? value
environment[value]
else
raise 'Uninitialized variable during evaluation.'
end
end
def derive(variable)
if value == variable
Number::ONE
else
Number::ZERO
end
end
def exact?
false
end
end
class Composite < Expr
attr_accessor :args
def initialize(*args)
@args = args
end
def self.build(s_args)
new(*s_args.map { |s_expr| Expr.build(s_expr) })
end
alias state args
def evaluate(environment = {})
self.class.compute_value(*args.map { |expr| expr.evaluate(environment) })
end
def derive(variable)
arg_derives = args.map { |expr| expr.derive(variable) }
self.class.compute_derivative(*args, *arg_derives).simplify
end
def exact?
args.all? { |expr| expr.exact? }
end
def self.simplify_step(whole, *_)
whole
end
def simplify
if exact?
Number.new(evaluate)
else
simple_args = args.map { |expr| expr.simplify }
whole = self.class.new(*simple_args)
self.class.simplify_step(whole, *simple_args)
end
end
end
class Addition < Composite
@@types[:+] = self
def self.compute_value(a, b)
a + b
end
def self.compute_derivative(f, g, df, dg)
df + dg
end
def self.simplify_step(whole, a, b)
if a == Number::ZERO
b
elsif b == Number::ZERO
a
else
whole
end
end
end
class Multiplication < Composite
@@types[:*] = self
def self.compute_value(a, b)
a * b
end
def self.compute_derivative(f, g, df, dg)
df * g + f * dg
end
def self.simplify_step(whole, a, b)
if a == Number::ZERO or b == Number::ZERO
Number::ZERO
elsif a == Number::ONE
b
elsif b == Number::ONE
a
else
whole
end
end
end
class Negation < Composite
@@types[:-] = self
def self.compute_value(a)
-a
end
def self.compute_derivative(f, df)
-df
end
def self.simplify_step(whole, a)
if Negation == a.class
a.args.first
else
whole
end
end
end
class Sine < Composite
@@types[:sin] = self
def self.compute_value(a)
Math.sin(a)
end
def self.compute_derivative(f, df)
df * Cosine.new(f)
end
end
class Cosine < Composite
@@types[:cos] = self
def self.compute_value(a)
Math.cos(a)
end
def self.compute_derivative(f, df)
df * -Sine.new(f)
end
end

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

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

Finished in 0.04987 seconds
13 examples, 0 failures

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

Красимир обнови решението на 09.11.2012 21:37 (преди около 12 години)

+class Expr
+ @@types = {}
+
+ def ==(other)
+ other.class == self.class and other.state == state
+ end
+
+ def self.build(s_expr)
+ type, *s_args = *s_expr
+ @@types[type].build(s_args)
+ end
+
+ def +(other)
+ Addition.new(self, other)
+ end
+
+ def *(other)
+ Multiplication.new(self, other)
+ end
+
+ def -@
+ Negation.new(self)
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Atomic < Expr
+ attr_accessor :value
+
+ def initialize(value)
+ @value = value
+ end
+
+ def self.build(value)
+ new value.first
+ end
+
+ alias state value
+end
+
+class Number < Atomic
+ @@types[:number] = self
+
+ Zero = self.new(0)
+ One = self.new(1)
+
+ def evaluate(environment = {})
+ value
+ end
+
+ def derive(variable)
+ Zero
+ end
+
+ def exact?
+ true
+ end
+end
+
+class Variable < Atomic
+ @@types[:variable] = self
+
+ def evaluate(environment = {})
+ if environment.has_key? value
+ environment[value]
+ else
+ raise 'Uninitialized variable during evaluation.'
+ end
+ end
+
+ def derive(variable)
+ if value == variable
+ Number::One
+ else
+ Number::Zero
+ end
+ end
+
+ def exact?
+ false
+ end
+end
+
+class Composite < Expr
+ attr_accessor :args
+
+ def initialize(*args)
+ @args = args
+ end
+
+ def self.build(s_args)
+ new(*s_args.map { |s_expr| Expr.build(s_expr) })
+ end
+
+ alias state args
+
+ def evaluate(environment = {})
+ self.class.compute_value(*args.map { |expr| expr.evaluate(environment) })
+ end
+
+ def derive(variable)
+ arg_derives = args.map { |expr| expr.derive(variable) }
+ self.class.compute_derivative(*args, *arg_derives).simplify
+ end
+
+ def exact?
+ args.all? { |expr| expr.exact? }
+ end
+
+ def self.simplify_step(whole, *_)
+ whole
+ end
+
+ def simplify
+ if exact?
+ Number.new(evaluate)
+ else
+ simple_args = args.map { |expr| expr.simplify }
+ whole = self.class.new(*simple_args)
+ self.class.simplify_step(whole, *simple_args)
+ end
+ end
+end
+
+class Addition < Composite
+ @@types[:+] = self
+
+ def self.compute_value(a, b)
+ a + b
+ end
+
+ def self.compute_derivative(f, g, df, dg)
+ df + dg
+ end
+
+ def self.simplify_step(whole, a, b)
+ if a == Number::Zero
+ b
+ elsif b == Number::Zero
+ a
+ else
+ whole
+ end
+ end
+end
+
+class Multiplication < Composite
+ @@types[:*] = self
+
+ def self.compute_value(a, b)
+ a * b
+ end
+
+ def self.compute_derivative(f, g, df, dg)
+ df * g + f * dg
+ end
+
+ def self.simplify_step(whole, a, b)
+ if a == Number::Zero or b == Number::Zero
+ Number::Zero
+ elsif a == Number::One
+ b
+ elsif b == Number::One
+ a
+ else
+ whole
+ end
+ end
+end
+
+class Negation < Composite
+ @@types[:-] = self
+
+ def self.compute_value(a)
+ -a
+ end
+
+ def self.compute_derivative(f, df)
+ -df
+ end
+
+ def self.simplify_step(whole, a)
+ if Negation == a.class
+ a.args.first
+ else
+ whole
+ end
+ end
+end
+
+class Sine < Composite
+ @@types[:sin] = self
+
+ def self.compute_value(a)
+ Math.sin(a)
+ end
+
+ def self.compute_derivative(f, df)
+ df * Cosine.new(f)
+ end
+end
+
+class Cosine < Composite
+ @@types[:cos] = self
+
+ def self.compute_value(a)
+ Math.cos(a)
+ end
+
+ def self.compute_derivative(f, df)
+ df * -Sine.new(f)
+ end
+end

Красимир обнови решението на 09.11.2012 22:50 (преди около 12 години)

class Expr
@@types = {}
def ==(other)
other.class == self.class and other.state == state
end
def self.build(s_expr)
type, *s_args = *s_expr
@@types[type].build(s_args)
end
def +(other)
Addition.new(self, other)
end
def *(other)
Multiplication.new(self, other)
end
def -@
Negation.new(self)
end
def simplify
self
end
end
class Atomic < Expr
attr_accessor :value
def initialize(value)
@value = value
end
def self.build(value)
new value.first
end
alias state value
end
class Number < Atomic
@@types[:number] = self
- Zero = self.new(0)
- One = self.new(1)
+ ZERO = self.new(0)
+ ONE = self.new(1)
def evaluate(environment = {})
value
end
def derive(variable)
- Zero
+ ZERO
end
def exact?
true
end
end
class Variable < Atomic
@@types[:variable] = self
def evaluate(environment = {})
if environment.has_key? value
environment[value]
else
raise 'Uninitialized variable during evaluation.'
end
end
def derive(variable)
if value == variable
- Number::One
+ Number::ONE
else
- Number::Zero
+ Number::ZERO
end
end
def exact?
false
end
end
class Composite < Expr
attr_accessor :args
def initialize(*args)
@args = args
end
def self.build(s_args)
new(*s_args.map { |s_expr| Expr.build(s_expr) })
end
alias state args
def evaluate(environment = {})
self.class.compute_value(*args.map { |expr| expr.evaluate(environment) })
end
def derive(variable)
arg_derives = args.map { |expr| expr.derive(variable) }
self.class.compute_derivative(*args, *arg_derives).simplify
end
def exact?
args.all? { |expr| expr.exact? }
end
def self.simplify_step(whole, *_)
whole
end
def simplify
if exact?
Number.new(evaluate)
else
simple_args = args.map { |expr| expr.simplify }
whole = self.class.new(*simple_args)
self.class.simplify_step(whole, *simple_args)
end
end
end
class Addition < Composite
@@types[:+] = self
def self.compute_value(a, b)
a + b
end
def self.compute_derivative(f, g, df, dg)
df + dg
end
def self.simplify_step(whole, a, b)
- if a == Number::Zero
+ if a == Number::ZERO
b
- elsif b == Number::Zero
+ elsif b == Number::ZERO
a
else
whole
end
end
end
class Multiplication < Composite
@@types[:*] = self
def self.compute_value(a, b)
a * b
end
def self.compute_derivative(f, g, df, dg)
df * g + f * dg
end
def self.simplify_step(whole, a, b)
- if a == Number::Zero or b == Number::Zero
- Number::Zero
- elsif a == Number::One
+ if a == Number::ZERO or b == Number::ZERO
+ Number::ZERO
+ elsif a == Number::ONE
b
- elsif b == Number::One
+ elsif b == Number::ONE
a
else
whole
end
end
end
class Negation < Composite
@@types[:-] = self
def self.compute_value(a)
-a
end
def self.compute_derivative(f, df)
-df
end
def self.simplify_step(whole, a)
if Negation == a.class
a.args.first
else
whole
end
end
end
class Sine < Composite
@@types[:sin] = self
def self.compute_value(a)
Math.sin(a)
end
def self.compute_derivative(f, df)
df * Cosine.new(f)
end
end
class Cosine < Composite
@@types[:cos] = self
def self.compute_value(a)
Math.cos(a)
end
def self.compute_derivative(f, df)
df * -Sine.new(f)
end
end