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

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

Към профила на Тодор Ганчев

Резултати

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

Код

class UndefinedVariableError < StandardError
end
class Expr
attr_accessor :s_expr
def initialize(s_expr)
@s_expr = s_expr
end
def self.build(s_expr)
new s_expr
end
def ==(other_expr)
s_expr == other_expr.s_expr
end
def +(other_expr)
Expr.build [:+, s_expr, other_expr.s_expr]
end
def *(other_expr)
Expr.build [:*, s_expr, other_expr.s_expr]
end
def -@
Expr.build [:-, s_expr]
end
def evaluate(environment = {})
case s_expr[0]
when :number then return Number.build(s_expr).evaluate(environment)
when :variable then return Variable.build(s_expr).evaluate(environment)
when :+ then return Addition.build(s_expr).evaluate(environment)
when :* then return Multiplication.build(s_expr).evaluate(environment)
when :- then return Negation.build(s_expr).evaluate(environment)
when :sin then return Sine.build(s_expr).evaluate(environment)
when :cos then return Cosine.build(s_expr).evaluate(environment)
end
end
def derive(variable)
case s_expr[0]
when :number then return Number.build(s_expr).derive(variable).simplify
when :variable then return Variable.build(s_expr).derive(variable).simplify
when :+ then return Addition.build(s_expr).derive(variable).simplify
when :* then return Multiplication.build(s_expr).derive(variable).simplify
when :- then return Negation.build(s_expr).derive(variable).simplify
when :sin then return Sine.build(s_expr).derive(variable).simplify
when :cos then return Cosine.build(s_expr).derive(variable).simplify
end
end
def simplify
case s_expr[0]
when :number then return Number.build(s_expr).simplify
when :variable then return Variable.build(s_expr).simplify
when :+ then return Addition.build(s_expr).simplify
when :* then return Multiplication.build(s_expr).simplify
when :- then return Negation.build(s_expr).simplify
when :sin then return Sine.build(s_expr).simplify
when :cos then return Cosine.build(s_expr).simplify
end
end
end
class Unary < Expr
def operand
s_expr[1]
end
end
class Binary < Expr
def operand1
s_expr[1]
end
def operand2
s_expr[2]
end
end
class Number < Unary
def evaluate(environment = {})
operand
end
def simplify
self
end
def derive(variable)
Expr.build [:number, 0]
end
end
class Variable < Unary
def evaluate(environment = {})
if environment.has_key? operand
environment[operand]
else
raise UndefinedVariableError
end
end
def simplify
self
end
def derive(variable)
if operand == variable
return Expr.build [:number, 1]
else
return Expr.build [:number, 0]
end
end
end
class Addition < Binary
def evaluate(environment = {})
Expr.build(operand1).evaluate(environment) + Expr.build(operand2).evaluate(environment)
end
def simplify
begin
return Expr.build [:number, evaluate]
rescue UndefinedVariableError
if Expr.build(operand1).simplify == Expr.build([:number, 0])
return Expr.build(operand2).simplify
elsif Expr.build(operand2).simplify == Expr.build([:number, 0])
return Expr.build(operand1).simplify
else
return Expr.build(operand1).simplify + Expr.build(operand2).simplify
end
end
end
def derive(variable)
Expr.build(operand1).derive(variable) + Expr.build(operand2).derive(variable)
end
end
class Multiplication < Binary
def evaluate(environment = {})
Expr.build(operand1).evaluate(environment) * Expr.build(operand2).evaluate(environment)
end
def simplify
begin
return Expr.build [:number, evaluate]
rescue UndefinedVariableError
if Expr.build(operand1).simplify == Expr.build([:number, 1])
return Expr.build(operand2).simplify
elsif Expr.build(operand2).simplify == Expr.build([:number, 1])
return Expr.build(operand1).simplify
elsif Expr.build(operand1).simplify == Expr.build([:number, 0]) or
Expr.build(operand2).simplify == Expr.build([:number, 0])
return Expr.build [:number, 0]
else
return Expr.build(operand1).simplify * Expr.build(operand2).simplify
end
end
end
def derive(variable)
Expr.build(operand1).derive(variable) * Expr.build(operand2) +
Expr.build(operand1) * Expr.build(operand2).derive(variable)
end
end
class Negation < Unary
def evaluate(environment = {})
- Expr.build(operand).evaluate(environment)
end
def simplify
begin
return Expr.build [:number, evaluate]
rescue UndefinedVariableError
return - Expr.build(operand).simplify
end
end
def derive(variable)
- Expr.build(operand).derive(variable)
end
end
class Sine < Unary
def evaluate(environment = {})
Math.sin Expr.build(operand).evaluate(environment)
end
def simplify
begin
return Expr.build [:number, evaluate]
rescue UndefinedVariableError
return Expr.build [:sin, Expr.build(operand).simplify.s_expr]
end
end
def derive(variable)
Expr.build(operand).derive(variable) * Cosine.build(operand)
end
end
class Cosine < Unary
def evaluate(environment = {})
Math.cos Expr.build(operand).evaluate(environment)
end
def simplify
begin
return Expr.build [:number, evaluate]
rescue UndefinedVariableError
return Expr.build [:cos, Expr.build(operand).simplify.s_expr]
end
end
def derive(variable)
Expr.build(operand).derive(variable) * (- Sine.build(operand))
end
end

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

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

Finished in 0.05321 seconds
13 examples, 0 failures

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

Тодор обнови решението на 14.11.2012 14:41 (преди над 11 години)

+class UndefinedVariableError < StandardError
+end
+
+class Expr
+ attr_accessor :s_expr
+
+ def initialize(s_expr)
+ @s_expr = s_expr
+ end
+
+ def self.build(s_expr)
+ new s_expr
+ end
+
+ def ==(other_expr)
+ s_expr == other_expr.s_expr
+ end
+
+ def +(other_expr)
+ Expr.build [:+, s_expr, other_expr.s_expr]
+ end
+
+ def *(other_expr)
+ Expr.build [:*, s_expr, other_expr.s_expr]
+ end
+
+ def -@
+ Expr.build [:-, s_expr]
+ end
+
+ def evaluate(environment = {})
+ case s_expr[0]
+ when :number then return Number.build(s_expr).evaluate(environment)
+ when :variable then return Variable.build(s_expr).evaluate(environment)
+ when :+ then return Addition.build(s_expr).evaluate(environment)
+ when :* then return Multiplication.build(s_expr).evaluate(environment)
+ when :- then return Negation.build(s_expr).evaluate(environment)
+ when :sin then return Sine.build(s_expr).evaluate(environment)
+ when :cos then return Cosine.build(s_expr).evaluate(environment)
+ end
+ end
+
+ def derive(variable)
+ case s_expr[0]
+ when :number then return Number.build(s_expr).derive(variable).simplify
+ when :variable then return Variable.build(s_expr).derive(variable).simplify
+ when :+ then return Addition.build(s_expr).derive(variable).simplify
+ when :* then return Multiplication.build(s_expr).derive(variable).simplify
+ when :- then return Negation.build(s_expr).derive(variable).simplify
+ when :sin then return Sine.build(s_expr).derive(variable).simplify
+ when :cos then return Cosine.build(s_expr).derive(variable).simplify
+ end
+ end
+
+ def simplify
+ case s_expr[0]
+ when :number then return Number.build(s_expr).simplify
+ when :variable then return Variable.build(s_expr).simplify
+ when :+ then return Addition.build(s_expr).simplify
+ when :* then return Multiplication.build(s_expr).simplify
+ when :- then return Negation.build(s_expr).simplify
+ when :sin then return Sine.build(s_expr).simplify
+ when :cos then return Cosine.build(s_expr).simplify
+ end
+ end
+
+end
+
+class Unary < Expr
+ def operand
+ s_expr[1]
+ end
+end
+
+class Binary < Expr
+ def operand1
+ s_expr[1]
+ end
+
+ def operand2
+ s_expr[2]
+ end
+end
+
+class Number < Unary
+ def evaluate(environment = {})
+ operand
+ end
+
+ def simplify
+ self
+ end
+
+ def derive(variable)
+ Expr.build [:number, 0]
+ end
+end
+
+class Variable < Unary
+ def evaluate(environment = {})
+ if environment.has_key? operand
+ environment[operand]
+ else
+ raise UndefinedVariableError
+ end
+ end
+
+ def simplify
+ self
+ end
+
+ def derive(variable)
+ if operand == variable
+ return Expr.build [:number, 1]
+ else
+ return Expr.build [:number, 0]
+ end
+ end
+end
+
+class Addition < Binary
+ def evaluate(environment = {})
+ Expr.build(operand1).evaluate(environment) + Expr.build(operand2).evaluate(environment)
+ end
+
+ def simplify
+ begin
+ return Expr.build [:number, evaluate]
+ rescue UndefinedVariableError
+ if Expr.build(operand1).simplify == Expr.build([:number, 0])
+ return Expr.build(operand2).simplify
+ elsif Expr.build(operand2).simplify == Expr.build([:number, 0])
+ return Expr.build(operand1).simplify
+ else
+ return Expr.build(operand1).simplify + Expr.build(operand2).simplify
+ end
+ end
+ end
+
+ def derive(variable)
+ Expr.build(operand1).derive(variable) + Expr.build(operand2).derive(variable)
+ end
+end
+
+class Multiplication < Binary
+ def evaluate(environment = {})
+ Expr.build(operand1).evaluate(environment) * Expr.build(operand2).evaluate(environment)
+ end
+
+ def simplify
+ begin
+ return Expr.build [:number, evaluate]
+ rescue UndefinedVariableError
+ if Expr.build(operand1).simplify == Expr.build([:number, 1])
+ return Expr.build(operand2).simplify
+ elsif Expr.build(operand2).simplify == Expr.build([:number, 1])
+ return Expr.build(operand1).simplify
+ elsif Expr.build(operand1).simplify == Expr.build([:number, 0]) or
+ Expr.build(operand2).simplify == Expr.build([:number, 0])
+ return Expr.build [:number, 0]
+ else
+ return Expr.build(operand1).simplify * Expr.build(operand2).simplify
+ end
+ end
+ end
+
+ def derive(variable)
+ Expr.build(operand1).derive(variable) * Expr.build(operand2) +
+ Expr.build(operand1) * Expr.build(operand2).derive(variable)
+ end
+end
+
+class Negation < Unary
+ def evaluate(environment = {})
+ - Expr.build(operand).evaluate(environment)
+ end
+
+ def simplify
+ begin
+ return Expr.build [:number, evaluate]
+ rescue UndefinedVariableError
+ return - Expr.build(operand).simplify
+ end
+ end
+
+ def derive(variable)
+ - Expr.build(operand).derive(variable)
+ end
+end
+
+class Sine < Unary
+ def evaluate(environment = {})
+ Math.sin Expr.build(operand).evaluate(environment)
+ end
+
+ def simplify
+ begin
+ return Expr.build [:number, evaluate]
+ rescue UndefinedVariableError
+ return Expr.build [:sin, Expr.build(operand).simplify.s_expr]
+ end
+ end
+
+ def derive(variable)
+ Expr.build(operand).derive(variable) * Cosine.build(operand)
+ end
+end
+
+class Cosine < Unary
+ def evaluate(environment = {})
+ Math.cos Expr.build(operand).evaluate(environment)
+ end
+
+ def simplify
+ begin
+ return Expr.build [:number, evaluate]
+ rescue UndefinedVariableError
+ return Expr.build [:cos, Expr.build(operand).simplify.s_expr]
+ end
+ end
+
+ def derive(variable)
+ Expr.build(operand).derive(variable) * (- Sine.build(operand))
+ end
+end