Бисер обнови решението на 23.10.2014 16:11 (преди около 10 години)
+class Filter
+
+ def initialize(&bl)
+ @block = bl
+ end
+
+ def check(value)
+ @block.call value
+ end
+
+ def &(other)
+ Filter.new { |x| self.check x and other.check x}
+ end
+
+ def |(other)
+ Filter.new { |x| self.check x or other.check x }
+ end
+
+end
+
+class SignFilter < Filter
+
+ def initialize(sign)
+ case sign
+ when :positive then @block = ->(x) { x > 0 }
+ when :negative then @block = ->(x) { x < 0 }
+ when :non_positive then @block = ->(x) { x <= 0 }
+ when :non_negative then @block = ->(x) { x >= 0 }
+ end
+ end
+
+end
+
+class TypeFilter < Filter
+
+ def initialize(sign)
+ case sign
+ when :integer then @block = ->(x) { x.is_a? Integer }
+ when :real then @block = ->(x) { x.is_a? Float or x.is_a? Rational }
+ when :complex then @block = ->(x) { x.is_a? Complex }
+ end
+ end
+
+end
+
+class NumberSet
+ include Enumerable
+
+ def initialize
+ @numbers = []
+ end
+
+ def each &block
+ @numbers.each do |number|
+ if block_given? then
+ block.call number
+ else
+ yield number
+ end
+ end
+ end
+
+ def size
+ @numbers.size
+ end
+
+ def check_type(number)
+ number.is_a? Fixnum or
+ number.is_a? Float or
+ number.is_a? Rational or
+ number.is_a? Complex
+ end
+
+ def <<(number)
+ return nil if @numbers.include? number
+ return nil if not checkType number
+
+ @numbers.push number
+ end
+
+ def [](filter)
+ select { |x| filter.check x }
+ end
+end