Решение на Трета задача от Мирослав Крамолински

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

Към профила на Мирослав Крамолински

Резултати

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

Код

class Simplifier
def Simplifier.simplify(expr)
case expr[0]
when :number then expr
when :variable then expr
when :- then [:-, simplify(expr[1])]
when :* then expr = Simplifier.verify_multiplication(expr)
when :sin then expr = Simplifier.verify_sin(expr)
when :cos then expr
else expr = Simplifier.verify_addition(expr)
end
end
def Simplifier.verify_sin(expr)
arg = simplify(expr[1])
return arg if arg == [:number, 0]
[expr[0], arg]
end
def Simplifier.verify_addition(expr)
num, expr1, expr2 = [:number, 0], simplify(expr[1]), simplify(expr[2])
return expr2 if expr1 == num
return expr1 if expr2 == num
[expr[0], expr1, expr2]
end
def Simplifier.verify_multiplication(expr)
num_zero, num_one = [:number, 0], [:number, 1]
expr1, expr2 = simplify(expr[1]), simplify(expr[2])
return num_zero if expr1 == num_zero || expr2 == num_zero
return expr2 if expr1 == num_one
return expr1 if expr2 == num_one
[expr[0], expr1, expr2]
end
end
class Derive
def Derive.derive(expr, arg)
case expr[0]
when :number then [:number, 0]
when :variable then variable_evaluate(expr[1], arg)
when :- then [expr[0], derive(expr[1], arg)]
when :sin then [:*, derive(expr[1], arg), [:cos, expr[1]]]
when :cos then [:*, derive(expr[1], arg), [:-, [:sin, expr[1]]]]
when :+ then [:+, derive(expr[1], arg), derive(expr[2], arg)]
when :* then complex_multiplication(expr, arg)
end
end
def Derive.variable_evaluate(expr, arg)
return [:number, 1] if arg == expr
[:number, 0]
end
def Derive.complex_multiplication(expr, arg)
product = [:+]
product << [:*, derive(expr[1], arg), expr[2]]
product << [:*, expr[1], derive(expr[2], arg)]
product
end
end
class Expr
attr_reader :expr
include Math
def initialize(s_expression)
@expr = s_expression
@vars = false
end
def Expr.build(s_expression)
self.new(s_expression)
end
def exact?(expr = @expr)
case expr[0]
when :variable then @vars = true
when :number then @vars
when :+ then exact?(expr[1]) || exact?(expr[2])
when :* then exact?(expr[1]) || exact?(expr[2])
else exact?(expr[1])
end
end
def ==(expr)
@expr == expr.expr
end
def evaluate(environment = {})
calc_expr(@expr, environment)
end
def calc_expr(expr, env = {})
return expr if expr.kind_of? Integer
return expr if expr.kind_of? Float
case expr[0]
when :number then calc_expr(expr[1], env)
when :variable then env.fetch(expr[1])
when :sin then sin(calc_expr(expr[1], env))
when :cos then cos(calc_expr(expr[1], env))
when :- then calc_expr([:*, [:number, -1], expr[1]],env)
else calc_expr(expr[1], env).send expr[0], calc_expr(expr[2], env)
end
end
def simplify
@vars = false
@simplified = Simplifier.simplify(@expr)
if !Expr.build(@simplified).exact?
Expr.build([:number, Expr.build(@simplified).evaluate])
else
Expr.build(@simplified)
end
end
def derive(arg)
expr = Derive.derive(Simplifier.simplify(@expr), arg)
@simplified = Simplifier.simplify(expr)
if !Expr.build(@simplified).exact?
Expr.build([:number, Expr.build(@simplified).evaluate])
else
Expr.build(@simplified)
end
end
end

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

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

Finished in 0.0497 seconds
13 examples, 0 failures

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

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

+class Simplifier
+ def Simplifier.simplify(expr)
+ case expr[0]
+ when :number then expr
+ when :variable then expr
+ when :- then [:-, simplify(expr[1])]
+ when :* then expr = Simplifier.verify_multiplication(expr)
+ when :sin then expr = Simplifier.verify_sin(expr)
+ when :cos then expr
+ else expr = Simplifier.verify_addition(expr)
+ end
+ end
+
+ def Simplifier.verify_sin(expr)
+ arg = simplify(expr[1])
+ return arg if arg == [:number, 0]
+ [expr[0], arg]
+ end
+
+ def Simplifier.verify_addition(expr)
+ num, expr1, expr2 = [:number, 0], simplify(expr[1]), simplify(expr[2])
+ return expr2 if expr1 == num
+ return expr1 if expr2 == num
+ [expr[0], expr1, expr2]
+ end
+
+ def Simplifier.verify_multiplication(expr)
+ num_zero, num_one = [:number, 0], [:number, 1]
+ expr1, expr2 = simplify(expr[1]), simplify(expr[2])
+ return num_zero if expr1 == num_zero || expr2 == num_zero
+ return expr2 if expr1 == num_one
+ return expr1 if expr2 == num_one
+ [expr[0], expr1, expr2]
+ end
+end
+
+class Derive
+ def Derive.derive(expr, arg)
+ case expr[0]
+ when :number then [:number, 0]
+ when :variable then variable_evaluate(expr[1], arg)
+ when :- then [expr[0], derive(expr[1], arg)]
+ when :sin then [:*, derive(expr[1], arg), [:cos, expr[1]]]
+ when :cos then [:*, derive(expr[1], arg), [:-, [:sin, expr[1]]]]
+ when :+ then [:+, derive(expr[1], arg), derive(expr[2], arg)]
+ when :* then complex_multiplication(expr, arg)
+ end
+ end
+
+ def Derive.variable_evaluate(expr, arg)
+ return [:number, 1] if arg == expr
+ [:number, 0]
+ end
+
+ def Derive.complex_multiplication(expr, arg)
+ product = [:+]
+ product << [:*, derive(expr[1], arg), expr[2]]
+ product << [:*, expr[1], derive(expr[2], arg)]
+ product
+ end
+end
+
+class Expr
+ attr_reader :expr
+ include Math
+
+ def initialize(s_expression)
+ @expr = s_expression
+ @vars = false
+ end
+
+ def Expr.build(s_expression)
+ self.new(s_expression)
+ end
+
+ def exact?(expr = @expr)
+ case expr[0]
+ when :variable then @vars = true
+ when :number then @vars
+ when :+ then exact?(expr[1]) || exact?(expr[2])
+ when :* then exact?(expr[1]) || exact?(expr[2])
+ else exact?(expr[1])
+ end
+ end
+
+ def ==(expr)
+ @expr == expr.expr
+ end
+
+ def evaluate(environment = {})
+ calc_expr(@expr, environment)
+ end
+
+ def calc_expr(expr, env = {})
+ return expr if expr.kind_of? Integer
+ return expr if expr.kind_of? Float
+ case expr[0]
+ when :number then calc_expr(expr[1], env)
+ when :variable then env.fetch(expr[1])
+ when :sin then sin(calc_expr(expr[1], env))
+ when :cos then cos(calc_expr(expr[1], env))
+ when :- then calc_expr([:*, [:number, -1], expr[1]],env)
+ else calc_expr(expr[1], env).send expr[0], calc_expr(expr[2], env)
+ end
+ end
+
+ def simplify
+ @vars = false
+ @simplified = Simplifier.simplify(@expr)
+ if !Expr.build(@simplified).exact?
+ Expr.build([:number, Expr.build(@simplified).evaluate])
+ else
+ Expr.build(@simplified)
+ end
+ end
+
+ def derive(arg)
+ expr = Derive.derive(Simplifier.simplify(@expr), arg)
+ @simplified = Simplifier.simplify(expr)
+ if !Expr.build(@simplified).exact?
+ Expr.build([:number, Expr.build(@simplified).evaluate])
+ else
+ Expr.build(@simplified)
+ end
+ end
+end