Веселин обнови решението на 27.10.2014 15:57 (преди около 10 години)
+module BaseFilter
+
+ def &(other)
+ composition = FilterComposition.new(:&)
+ composition.filters << self
+ composition.filters << other
+ composition
+ end
+
+ def |(other)
+ composition = FilterComposition.new(:|)
+ composition.filters << self
+ composition.filters << other
+ composition
+ end
+
+end
+
+class FilterComposition
+
+ include BaseFilter
+
+ attr_accessor :filters
+
+ def initialize(type)
+ @type = type
+ @filters = []
+ end
+
+ def call(element)
+ case @type
+ when :&
+ and_option(element)
+ when :|
+ or_option(element)
+ end
+ end
+
+ def and_option(element)
+ @filters.each do |filter|
+ return false unless filter.call(element)
+ end
+ true
+ end
+
+ def or_option(element)
+ @filters.map do |filter|
+ return true if filter.call(element)
+ end
+ false
+ end
+
+end
+
+class Filter
+
+ def initialize(&block)
+ @block = block
+ end
+
+ def call(element)
+ @block.call(element)
+ end
+
+end
+
+class TypeFilter
+
+ include BaseFilter
+
+ def initialize(type)
+ types = [:integer, :real, :complex]
+ @type = type
+ end
+
+ def call(element)
+ case @type
+ when :integer then element.is_a? Integer
+ when :real then (element.is_a?(Float) || element.is_a?(Rational))
+ when :complex then element.is_a? Complex
+ end
+ end
+
+end
+
+class SignFilter
+
+ include BaseFilter
+
+ def initialize(type)
+ types = [:positive, :non_positive, :negative, :non_negative]
+ @type = type
+ end
+
+ def call(element)
+ case @type
+ when :positive then element > 0
+ when :non_positive then element <= 0
+ when :negative then element < 0
+ when :non_negative then element >= 0
+ end
+ end
+
+end
+
+class NumberSet
+
+ include Enumerable
+
+ def initialize(elements = [])
+ @container = elements
+ end
+
+ def [](filter)
+ NumberSet.new(@container.select{ |element| filter.call(element) })
+ end
+
+ def each(&block)
+ @container.each do |element|
+ if block_given?
+ block.call element
+ else
+ yield element
+ end
+ end
+ end
+
+ def <<(number)
+ if (number.is_a? Numeric) && !(@container.include?(number))
+ @container << number
+ end
+ end
+
+ def print
+ @container.each do |x|
+ puts x
+ end
+ end
+
+ def size
+ @container.length
+ end
+
+ def empty?
+ @container.length == 0
+ end
+
+end