Решение на Втора задача от Теодор Драганов

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

Към профила на Теодор Драганов

Резултати

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

Код

class NumberSet < Array
def <<(number)
self.insert(-1, number) if not self.include? number
end
def [](filter)
NumberSet.new self.select {|number| filter.call number}
end
end
module FilterOperators
def &(filter)
Proc.new {|number| self.call(number) && filter.call(number)}
end
def |(filter)
Proc.new {|number| self.call(number) || filter.call(number)}
end
end
class Proc
include FilterOperators
end
class Filter
include FilterOperators
def initialize(&block)
@block = block
end
def call(number)
@block.call number
end
end
class TypeFilter
include FilterOperators
def initialize(number_type)
case number_type
when :integer then @number_type = [Integer]
when :real then @number_type = [Float, Rational]
when :complex then @number_type = [Complex]
end
end
def call(number)
@number_type.any? {|type| number.is_a? type}
end
end
class SignFilter
include FilterOperators
def initialize(sign_type)
case sign_type
when :positive then @sign_type = ">0"
when :non_negative then @sign_type = ">=0"
when :negative then @sign_type = "<0"
when :non_positive then @sign_type = "<=0"
end
@sign_type
end
def call(number)
eval(number.to_s + @sign_type)
end
end

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

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

Finished in 0.02996 seconds
24 examples, 0 failures

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

Теодор обнови решението на 27.10.2014 00:38 (преди около 10 години)

+class NumberSet < Array
+ def <<(number)
+ self.insert(-1, number) if not self.include? number
+ end
+
+ def [](filter)
+ NumberSet.new self.select {|number| filter.call number}
+ end
+end
+
+module FilterOperators
+ def &(filter)
+ Proc.new {|number| self.call(number) && filter.call(number)}
+ end
+
+ def |(filter)
+ Proc.new {|number| self.call(number) || filter.call(number)}
+ end
+end
+
+class Proc
+ include FilterOperators
+end
+
+class Filter
+ include FilterOperators
+ def initialize(&block)
+ @block = block
+ end
+
+ def call(number)
+ @block.call number
+ end
+end
+
+class TypeFilter
+ include FilterOperators
+ def initialize(number_type)
+ case number_type
+ when :integer then @number_type = [Integer]
+ when :real then @number_type = [Float, Rational]
+ when :complex then @number_type = [Complex]
+ end
+ end
+
+ def call(number)
+ @number_type.any? {|type| number.is_a? type}
+ end
+end
+
+class SignFilter
+ include FilterOperators
+ def initialize(sign_type)
+ case sign_type
+ when :positive then @sign_type = ">0"
+ when :non_negative then @sign_type = ">=0"
+ when :negative then @sign_type = "<0"
+ when :non_positive then @sign_type = "<=0"
+ end
+ @sign_type
+ end
+
+ def call(number)
+ eval(number.to_s + @sign_type)
+ end
+end
  • Не използвай self, излишно е в повечето случай, викай директно инстанционните методи.
  • eval IS EVIL. Определено е спомогнал с краткоста на решението, но го промени, тъкмо ще се отървеш и от @sign_type.
  • Monkey patching-а на Proc също не е добра идея, ако не мислиш като цяло да разширяваш функционалноста на пачваният клас, не го прави. В твоя случей го разширяваш да работи с конкретни класове и е далеч от generic.