Деян обнови решението на 26.10.2014 18:04 (преди около 10 години)
+require 'set'
+
+class NumberSet
+ include Enumerable
+
+ def initialize(numbers = [])
+ @numbers = Set.new(numbers)
+ end
+
+ def << (number)
+ unless @numbers.any? { |element| element == number }
+ @numbers << number
+ end
+ self
+ end
+
+ def [](filter)
+ filtered_set = @numbers.select { |number| filter.execute(number) }
+ NumberSet.new(filtered_set)
+ end
+
+ def size
+ @numbers.size
+ end
+
+ def empty?
+ @numbers.empty?
+ end
+
+ def each &block
+ @numbers.each &block
+ end
+
+ def to_s
+ @numbers.to_a.to_s
+ end
+end
+
+class Filter
+ def initialize &block
+ @filter = block
+ end
+
+ def execute number
+ @filter.call(number)
+ end
+
+ def &(filter)
+ Filter.new { |n| execute(n) & filter.execute(n) }
+ end
+
+ def |(filter)
+ Filter.new { |n| execute(n) | filter.execute(n) }
+ end
+end
+
+class TypeFilter < Filter
+ def initialize type
+ case type
+ when :integer then filter = ->(n) { n.is_a? Fixnum }
+ when :real then filter = ->(n) { n.is_a? Float or n.is_a? Rational }
+ when :complex then filter = ->(n) { n.is_a? Complex }
+ when :rational then filter = ->(n) { n.is_a? Rational }
+ end
+ super &filter
+ end
+end
+
+class SignFilter < Filter
+ def initialize sign
+ case sign
+ when :positive then filter = ->(n) { n > 0 }
+ when :non_positive then filter = ->(n) { n <= 0 }
+ when :negative then filter = ->(n) { n < 0 }
+ when :non_negative then filter = ->(n) { n >= 0 }
+ end
+ super &filter
+ end
+end