Кристиан обнови решението на 26.10.2014 16:39 (преди около 10 години)
+class NumberSet
+ include Enumerable
+
+ def initialize()
+ @numbers = []
+ end
+
+ def each
+ @numbers.each { |n| yield n }
+ end
+
+ def <<(number)
+ unless contains? number
+ @numbers << number
+ end
+ end
+
+ def size
+ @numbers.size
+ end
+
+ def empty?
+ @numbers.empty?
+ end
+
+ def [](filter)
+ result = NumberSet.new
+ @numbers.select { |number| filter.accepts? number }.each do |n|
+ result << n
+ end
+ result
+ end
+
+ private
+
+ def contains?(number)
+ @numbers.each do |n|
+ return true if (n <=> number) == 0
+ end
+ false
+ end
+end
+
+class BaseFilter
+ def initialize(&block)
+ @block = block
+ end
+
+ def accepts?(number)
+ @block.(number)
+ end
+
+ def &(other_filter)
+ BaseFilter.new { |number| accepts? number and other_filter.accepts? number }
+ end
+
+ def |(other_filter)
+ BaseFilter.new { |number| accepts? number or other_filter.accepts? number }
+ end
+end
+
+class Filter < BaseFilter
+ def initialize(&block)
+ super(&block)
+ end
+end
+
+class TypeFilter < BaseFilter
+ def initialize(type)
+ case type
+ when :integer then super() { |number| number.integer? }
+ when :real then super() { |n| n.is_a? Float or n.is_a? Rational }
+ when :complex then super() { |number| not number.real? }
+ end
+ end
+end
+
+class SignFilter < BaseFilter
+ def initialize(sign)
+ case sign
+ when :positive then super() { |number| number > 0 }
+ when :non_positive then super() { |number| number <= 0 }
+ when :negative then super() { |number| number < 0 }
+ when :non_negative then super() { |number| number >= 0 }
+ end
+ end
+end