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

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

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

Резултати

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

Код

class Expr
def self.build(expression)
if expression[0] == :+ or expression[0] == :* then Binary.build(expression)
else Unary.build(expression)
end
end
end
class Unary < Expr
def self.build(expression)
if expression[0] == :number then (Number.new(expression[1])).simplify
elsif expression[0] == :variable then (Variable.new(expression[1])).simplify
elsif expression[0] == :- then (Negation.new(Expr.build(expression[1]))).simplify
elsif expression[0] == :sin then (Sine.new(Expr.build(expression[1]))).simplify
else (Cosine.new(Expr.build(expression[1]))).simplify
end
end
end
class Binary < Expr
def self.build(expression)
if expression[0] == :+
(Addition.new(Expr.build(expression[1]), Expr.build(expression[2]))).simplify
else (Multiplication.new(Expr.build(expression[1]), Expr.build(expression[2]))).simplify
end
end
end
class Number < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
Number.new(0)
end
def ==(other_number)
if not other_number.instance_of? Number then return false
end
operand == other_number.operand
end
def evaluate(environment = {})
operand
end
def exact?
false
end
def simplify
self
end
end
class Addition < Binary
attr_accessor :operand1, :operand2
def initialize(operand1, operand2)
@operand1 = operand1
@operand2 = operand2
end
def derive(variable)
(Addition.new(operand1.derive(variable), operand2.derive(variable))).simplify
end
def ==(other_addition)
if not other_addition.instance_of? Addition then return false
end
operand1 == other_addition.operand1 and operand2 == other_addition.operand2
end
def evaluate(environment = {})
operand1.evaluate(environment) + operand2.evaluate(environment)
end
def exact?
operand1.exact? or operand2.exact?
end
def simplify
if not operand1.exact? and not operand2.exact?
return Number.new(operand1.evaluate + operand2.evaluate)
end
if not operand1.exact? and operand1.evaluate == 0 then return operand2.simplify
end
if not operand2.exact? and operand2.evaluate == 0 then return operand1.simplify
end
expression = Addition.new(operand1.simplify, operand2.simplify)
end
end
class Multiplication < Binary
attr_accessor :operand1, :operand2
def initialize(operand1, operand2)
@operand1 = operand1
@operand2 = operand2
end
def derive(variable)
(Addition.new Multiplication.new(operand1.derive(variable), operand2),
Multiplication.new(operand1, operand2.derive(variable))).simplify
end
def ==(other_multiplication)
if not other_multiplication.instance_of? Multiplication then return false
end
operand1 == other_multiplication.operand1 and operand2 == other_multiplication.operand2
end
def evaluate(environment = {})
operand1.evaluate(environment) * operand2.evaluate(environment)
end
def exact?
operand1.exact? or operand2.exact?
end
def simplify
if not operand1.exact? and not @operand2.exact?
return Number.new(operand1.evaluate * operand2.evaluate)
end
if not operand1.exact? and operand1.evaluate == 1 then return operand2.simplify
end
if not operand2.exact? and operand2.evaluate == 1 then return operand1.simplify
end
if not operand1.exact? and operand1.evaluate == 0 then return Number.new(0)
end
if not operand2.exact? and operand2.evaluate == 0 then return Number.new(0)
end
expression = Multiplication.new(operand1.simplify, operand2.simplify)
end
end
class Variable < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
if operand == variable then Number.new(1)
else Number.new(0)
end
end
def ==(other_variable)
if not other_variable.instance_of? Variable then return false
end
operand == other_variable.operand
end
def evaluate(environment = {})
environment.each { |key, value| if key == operand then return value end }
puts "There are no such variables in the expression or not enough arguments are given!"
exit
end
def exact?
true
end
def simplify
self
end
end
class Negation < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
(Negation.new(operand.derive(variable))).simplify
end
def ==(other_negation)
if not other_negation.instance_of? Negation then return false
end
operand == other_negation.operand
end
def evaluate(environment = {})
-(@operand.evaluate(environment))
end
def exact?
operand.exact?
end
def simplify
Negation.new(operand.simplify)
end
end
class Sine < Unary
include Math
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
(Multiplication.new(operand.derive(variable), Cosine.new(operand))).simplify
end
def ==(other_sine)
if not other_sine.instance_of? Sine then return false
end
operand == other_sine.operand
end
def evaluate(environment = {})
if not operand.exact? then return sin(@operand.evaluate)
end
sin(@operand.evaluate(environment))
end
def exact?
operand.exact?
end
def simplify
if not operand.exact? and operand.evaluate == 0 then return Number.new(0)
end
Sine.new(operand.simplify)
end
end
class Cosine < Unary
include Math
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
(Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand)))).simplify
end
def ==(other_cosine)
if not other_cosine.instance_of? Cosine then return false
end
operand == other_cosine.operand
end
def evaluate(environment = {})
if not operand.exact? then return cos(@operand.evaluate)
end
cos(@operand.evaluate(environment))
end
def exact?
operand.exact?
end
def simplify
Cosine.new(operand.simplify)
end
end

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

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

Finished in 0.04928 seconds
13 examples, 0 failures

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

Иван обнови решението на 12.11.2012 17:42 (преди над 11 години)

+class Expr
+ def self.build(expression)
+ if expression[0] == :+ or expression[0] == :* then Binary.build(expression)
+ else Unary.build(expression)
+ end
+ end
+end
+
+class Unary < Expr
+ def self.build(expression)
+ if expression[0] == :number then (Number.new(expression[1])).simplify
+ elsif expression[0] == :variable then (Variable.new(expression[1])).simplify
+ elsif expression[0] == :- then (Negation.new(Expr.build(expression[1]))).simplify
+ elsif expression[0] == :sin then (Sine.new(Expr.build(expression[1]))).simplify
+ else (Cosine.new(Expr.build(expression[1]))).simplify
+ end
+ end
+end
+
+class Binary < Expr
+ def self.build(expression)
+ if expression[0] == :+
+ (Addition.new(Expr.build(expression[1]), Expr.build(expression[2]))).simplify
+ else (Multiplication.new(Expr.build(expression[1]), Expr.build(expression[2]))).simplify
+ end
+ end
+end
+
+class Number < Unary
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def derive(variable)
+ Number.new(0)
+ end
+
+ def ==(other_number)
+ if not other_number.instance_of? Number then return false
+ end
+ operand == other_number.operand
+ end
+
+ def evaluate(environment = {})
+ operand
+ end
+
+ def exact?
+ false
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Addition < Binary
+ attr_accessor :operand1, :operand2
+
+ def initialize(operand1, operand2)
+ @operand1 = operand1
+ @operand2 = operand2
+ end
+
+ def derive(variable)
+ (Addition.new(operand1.derive(variable), operand2.derive(variable))).simplify
+ end
+
+ def ==(other_addition)
+ if not other_addition.instance_of? Addition then return false
+ end
+ operand1 == other_addition.operand1 and operand2 == other_addition.operand2
+ end
+
+ def evaluate(environment = {})
+ operand1.evaluate(environment) + operand2.evaluate(environment)
+ end
+
+ def exact?
+ operand1.exact? or operand2.exact?
+ end
+
+ def simplify
+ if not operand1.exact? and not operand2.exact?
+ return Number.new(operand1.evaluate + operand2.evaluate)
+ end
+ if not operand1.exact? and operand1.evaluate == 0 then return operand2.simplify
+ end
+ if not operand2.exact? and operand2.evaluate == 0 then return operand1.simplify
+ end
+ expression = Addition.new(operand1.simplify, operand2.simplify)
+ end
+end
+
+
+class Multiplication < Binary
+ attr_accessor :operand1, :operand2
+
+ def initialize(operand1, operand2)
+ @operand1 = operand1
+ @operand2 = operand2
+ end
+
+ def derive(variable)
+ (Addition.new Multiplication.new(operand1.derive(variable), operand2),
+ Multiplication.new(operand1, operand2.derive(variable))).simplify
+ end
+
+ def ==(other_multiplication)
+ if not other_multiplication.instance_of? Multiplication then return false
+ end
+ operand1 == other_multiplication.operand1 and operand2 == other_multiplication.operand2
+ end
+
+ def evaluate(environment = {})
+ operand1.evaluate(environment) * operand2.evaluate(environment)
+ end
+
+ def exact?
+ operand1.exact? or operand2.exact?
+ end
+
+ def simplify
+ if not operand1.exact? and not @operand2.exact?
+ return Number.new(operand1.evaluate * operand2.evaluate)
+ end
+ if not operand1.exact? and operand1.evaluate == 1 then return operand2.simplify
+ end
+ if not operand2.exact? and operand2.evaluate == 1 then return operand1.simplify
+ end
+ if not operand1.exact? and operand1.evaluate == 0 then return Number.new(0)
+ end
+ if not operand2.exact? and operand2.evaluate == 0 then return Number.new(0)
+ end
+ expression = Multiplication.new(operand1.simplify, operand2.simplify)
+ end
+end
+
+class Variable < Unary
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def derive(variable)
+ if operand == variable then Number.new(1)
+ else Number.new(0)
+ end
+ end
+
+ def ==(other_variable)
+ if not other_variable.instance_of? Variable then return false
+ end
+ operand == other_variable.operand
+ end
+
+ def evaluate(environment = {})
+ environment.each { |key, value| if key == operand then return value end }
+ puts "There are no such variables in the expression or not enough arguments are given!"
+ exit
+ end
+
+ def exact?
+ true
+ end
+
+ def simplify
+ self
+ end
+end
+
+class Negation < Unary
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def derive(variable)
+ (Multiplication.new(Number.new(-1), operand.derive(variable))).simplify
+ end
+
+ def ==(other_negation)
+ if not other_negation.instance_of? Negation then return false
+ end
+ operand == other_negation.operand
+ end
+
+ def evaluate(environment = {})
+ if operand.instance_of? Number then return -@operand.operand
+ end
+ environment.each { |key, value| if key == @operand.operand then return -value end }
+ end
+
+ def exact?
+ operand.exact?
+ end
+
+ def simplify
+ Negation.new(operand.simplify)
+ end
+end
+
+class Sine < Unary
+ include Math
+
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def derive(variable)
+ (Multiplication.new(operand.derive(variable), Cosine.new(operand))).simplify
+ end
+
+ def ==(other_sine)
+ if not other_sine.instance_of? Sine then return false
+ end
+ operand == other_sine.operand
+ end
+
+ def evaluate(environment = {})
+ if operand.instance_of? Number then return sin(@operand.operand)
+ end
+ environment.each { |key, value| if key == @operand.operand then return sin(value) end }
+ end
+
+ def exact?
+ operand.exact?
+ end
+
+ def simplify
+ if not operand.exact? and operand.evaluate == 0 then return Number.new(0)
+ end
+ Sine.new(operand.simplify)
+ end
+end
+
+class Cosine < Unary
+ include Math
+
+ attr_accessor :operand
+
+ def initialize(operand)
+ @operand = operand
+ end
+
+ def derive(variable)
+ Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand)))
+ end
+
+ def ==(other_cosine)
+ if not other_cosine.instance_of? Cosine then return false
+ end
+ operand == other_cosine.operand
+ end
+
+ def evaluate(environment = {})
+ if operand.instance_of? Number then return cos(@operand.operand)
+ end
+ environment.each { |key, value| if key == operand.operand then return cos(value) end }
+ end
+
+ def exact?
+ operand.exact?
+ end
+
+ def simplify
+ Cosine.new(operand.simplify)
+ end
+end

Иван обнови решението на 13.11.2012 02:42 (преди над 11 години)

class Expr
def self.build(expression)
if expression[0] == :+ or expression[0] == :* then Binary.build(expression)
else Unary.build(expression)
end
end
end
class Unary < Expr
def self.build(expression)
if expression[0] == :number then (Number.new(expression[1])).simplify
elsif expression[0] == :variable then (Variable.new(expression[1])).simplify
elsif expression[0] == :- then (Negation.new(Expr.build(expression[1]))).simplify
elsif expression[0] == :sin then (Sine.new(Expr.build(expression[1]))).simplify
else (Cosine.new(Expr.build(expression[1]))).simplify
end
end
end
class Binary < Expr
def self.build(expression)
if expression[0] == :+
(Addition.new(Expr.build(expression[1]), Expr.build(expression[2]))).simplify
else (Multiplication.new(Expr.build(expression[1]), Expr.build(expression[2]))).simplify
end
end
end
class Number < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
Number.new(0)
end
def ==(other_number)
if not other_number.instance_of? Number then return false
end
operand == other_number.operand
end
def evaluate(environment = {})
operand
end
def exact?
false
end
def simplify
self
end
end
class Addition < Binary
attr_accessor :operand1, :operand2
def initialize(operand1, operand2)
@operand1 = operand1
@operand2 = operand2
end
def derive(variable)
(Addition.new(operand1.derive(variable), operand2.derive(variable))).simplify
end
def ==(other_addition)
if not other_addition.instance_of? Addition then return false
end
operand1 == other_addition.operand1 and operand2 == other_addition.operand2
end
def evaluate(environment = {})
operand1.evaluate(environment) + operand2.evaluate(environment)
end
def exact?
operand1.exact? or operand2.exact?
end
def simplify
if not operand1.exact? and not operand2.exact?
return Number.new(operand1.evaluate + operand2.evaluate)
end
if not operand1.exact? and operand1.evaluate == 0 then return operand2.simplify
end
if not operand2.exact? and operand2.evaluate == 0 then return operand1.simplify
end
expression = Addition.new(operand1.simplify, operand2.simplify)
end
end
class Multiplication < Binary
attr_accessor :operand1, :operand2
def initialize(operand1, operand2)
@operand1 = operand1
@operand2 = operand2
end
def derive(variable)
(Addition.new Multiplication.new(operand1.derive(variable), operand2),
Multiplication.new(operand1, operand2.derive(variable))).simplify
end
def ==(other_multiplication)
if not other_multiplication.instance_of? Multiplication then return false
end
operand1 == other_multiplication.operand1 and operand2 == other_multiplication.operand2
end
def evaluate(environment = {})
operand1.evaluate(environment) * operand2.evaluate(environment)
end
def exact?
operand1.exact? or operand2.exact?
end
def simplify
if not operand1.exact? and not @operand2.exact?
return Number.new(operand1.evaluate * operand2.evaluate)
end
if not operand1.exact? and operand1.evaluate == 1 then return operand2.simplify
end
if not operand2.exact? and operand2.evaluate == 1 then return operand1.simplify
end
if not operand1.exact? and operand1.evaluate == 0 then return Number.new(0)
end
if not operand2.exact? and operand2.evaluate == 0 then return Number.new(0)
end
expression = Multiplication.new(operand1.simplify, operand2.simplify)
end
end
class Variable < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
if operand == variable then Number.new(1)
else Number.new(0)
end
end
def ==(other_variable)
if not other_variable.instance_of? Variable then return false
end
operand == other_variable.operand
end
def evaluate(environment = {})
environment.each { |key, value| if key == operand then return value end }
puts "There are no such variables in the expression or not enough arguments are given!"
exit
end
def exact?
true
end
def simplify
self
end
end
class Negation < Unary
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
- (Multiplication.new(Number.new(-1), operand.derive(variable))).simplify
+ (Negation.new(operand.derive(variable))).simplify
end
def ==(other_negation)
if not other_negation.instance_of? Negation then return false
end
operand == other_negation.operand
end
def evaluate(environment = {})
- if operand.instance_of? Number then return -@operand.operand
- end
- environment.each { |key, value| if key == @operand.operand then return -value end }
+ -(@operand.evaluate(environment))
end
def exact?
operand.exact?
end
def simplify
Negation.new(operand.simplify)
end
end
class Sine < Unary
include Math
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
(Multiplication.new(operand.derive(variable), Cosine.new(operand))).simplify
end
def ==(other_sine)
if not other_sine.instance_of? Sine then return false
end
operand == other_sine.operand
end
def evaluate(environment = {})
- if operand.instance_of? Number then return sin(@operand.operand)
+ if not operand.exact? then return sin(@operand.evaluate)
end
- environment.each { |key, value| if key == @operand.operand then return sin(value) end }
+ sin(@operand.evaluate(environment))
end
def exact?
operand.exact?
end
def simplify
if not operand.exact? and operand.evaluate == 0 then return Number.new(0)
end
Sine.new(operand.simplify)
end
end
class Cosine < Unary
include Math
attr_accessor :operand
def initialize(operand)
@operand = operand
end
def derive(variable)
- Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand)))
+ (Multiplication.new(operand.derive(variable), Negation.new(Sine.new(operand)))).simplify
end
def ==(other_cosine)
if not other_cosine.instance_of? Cosine then return false
end
operand == other_cosine.operand
end
def evaluate(environment = {})
- if operand.instance_of? Number then return cos(@operand.operand)
+ if not operand.exact? then return cos(@operand.evaluate)
end
- environment.each { |key, value| if key == operand.operand then return cos(value) end }
+ cos(@operand.evaluate(environment))
end
def exact?
operand.exact?
end
def simplify
Cosine.new(operand.simplify)
end
end