Йоана обнови решението на 23.10.2014 21:40 (преди около 10 години)
+class NumberSet
+ include Enumerable
+
+ def initialize
+ @set = []
+ end
+
+ def each(&block)
+ @set.each &block
+ end
+
+ def <<(new_number)
+ @set.none? { |number| number == new_number } && @set << new_number
+ end
+
+ def size
+ @set.size
+ end
+
+ def empty?
+ @set.empty?
+ end
+
+ def [](block)
+ @set.select { |number| block.call(number) }
+ end
+end
+
+class BaseFilter
+ def initialize(&block)
+ @block = block
+ end
+
+ def call(number)
+ @block.call(number)
+ end
+
+ def &(other)
+ BaseFilter.new do |number|
+ call(number) && other.call(number)
+ end
+ end
+
+ def |(other)
+ BaseFilter.new do |number|
+ call(number) || other.call(number)
+ end
+ end
+end
+
+class Filter < BaseFilter
+end
+
+class TypeFilter < BaseFilter
+ def initialize(type)
+ @block = send(type)
+ end
+
+ private
+
+ def integer
+ Proc.new { |number| number.is_a? Integer }
+ end
+
+ def real
+ Proc.new { |number| number.is_a?(Float) || number.is_a?(Rational) }
+ end
+
+ def complex
+ Proc.new { |number| number.is_a? Complex }
+ end
+end
+
+class SignFilter < BaseFilter
+ def initialize(sign)
+ @block = send(sign)
+ end
+
+ private
+
+ def positive
+ Proc.new { |number| number > 0 }
+ end
+
+ def non_positive
+ Proc.new { |number| number <= 0 }
+ end
+
+ def negative
+ Proc.new { |number| number < 0 }
+ end
+
+ def non_negative
+ Proc.new { |number| number >= 0 }
+ end
+end