Делян обнови решението на 27.10.2014 15:12 (преди около 11 години)
+class NumberSet
+  include Enumerable
+
+  def initialize
+    @numbers = []
+  end
+
+  def <<(number)
+    if not contains_number?(number)
+      @numbers << number
+    end
+  end
+
+  def [](filter)
+    filter_matches = @numbers.select { |number| filter.is_match? number }
+    NumberSet.new.merge filter_matches
+  end
+
+  def merge(array)
+    array.each { |number| @numbers << number }
+  end
+
+  def size
+    @numbers.size
+  end
+
+  def empty?
+    @numbers.size === 0
+  end
+
+  def each
+    @numbers.each { |number| yield number }
+  end
+
+  private
+
+  def contains_number?(number)
+    @numbers.any? { |current_number| number == current_number }
+  end
+end
+
+class Filter
+  def initialize(&block)
+    @block = block
+  end
+
+  def is_match?(number)
+    @block.call number
+  end
+
+  def &(other)
+    Filter.new { |number| self.is_match? number and other.is_match? number }
+  end
+
+  def |(other)
+    Filter.new { |number| self.is_match? number or other.is_match? number }
+  end
+end
+
+class TypeFilter < Filter
+  @@types = {
+             integer: Integer,
+             real: Float,
+             complex: Complex,
+            }
+
+  def initialize(type)
+    type = @@types.fetch type
+    super() { |number| number.is_a? type }
+  end
+end
+
+class SignFilter < Filter
+  @@sign_filters = {
+                    positive: Proc.new { |number| number > 0 },
+                    negative: Proc.new { |number| number < 0 },
+                    non_negative: Proc.new { |number| number >= 0 },
+                    non_positive: Proc.new { |number| number <= 0 },
+                   }
+
+  def initialize(sign)
+    sign_filter = @@sign_filters.fetch(sign)
+    super(&sign_filter)
+  end
+end
