Атанас обнови решението на 26.10.2014 21:34 (преди около 10 години)
+require 'set'
+class NumberSet
+ include Enumerable
+
+ def initialize
+ @complex_values_set = Set.new
+ @actual_values_set = Set.new
+ end
+
+ def <<(actual_value)
+ if actual_value.to_c.imag == 0
+ complex_value = Complex(actual_value.to_f, 0.to_f)
+ else
+ complex_value = Complex(actual_value.real.to_f, actual_value.imag.to_f)
+ end
+ size_before_add = @complex_values_set.count
+ @complex_values_set << complex_value
+ unless size_before_add == @complex_values_set.count
+ @actual_values_set << actual_value
+ end
+ end
+
+ def [](filter)
+ number_set = NumberSet.new
+ each do |item|
+ if filter.get_query.condition_satisfied?(item)
+ number_set << item
+ end
+ end
+ number_set
+ end
+
+ def each(&block)
+ @actual_values_set.each(&block)
+ end
+
+ def size
+ count
+ end
+
+ def empty?
+ any? ? false : true
+ end
+end
+
+module BaseFilter
+
+ def get_query()
+ @query
+ end
+
+ def &(filter)
+ old_query = Query.new
+ old_query.set_function(@query.get_function)
+ old_query.set_properties(@query.get_first, @query.get_second, @query.add?)
+ @query.set_properties(old_query, filter.get_query, true)
+ @query.set_function(nil)
+ self
+ end
+
+ def |(filter)
+ old_query = Query.new
+ old_query.set_function(@query.get_function)
+ old_query.set_properties(@query.get_first, @query.get_second, @query.add?)
+ @query.set_properties(old_query, filter.get_query, false)
+ @query.set_function(nil)
+ self
+ end
+end
+
+class SignFilter
+ include BaseFilter
+
+ def initialize(type)
+ @query = Query.new
+ case type
+ when :positive then @query.set_function(-> (number) {number > 0})
+ when :negative then @query.set_function(-> (number) {number < 0})
+ when :non_positive then @query.set_function(-> (number) {number <= 0})
+ when :non_negative then @query.set_function(-> (number) {number >= 0})
+ end
+ end
+end
+
+class TypeFilter
+ include BaseFilter
+
+ def initialize(type)
+ @query = Query.new
+ case type
+ when :integer then @query.set_function(-> (n) {n.class.name == "Fixnum"})
+ when :real then @query.set_function(-> (n) do
+ n.class.name == "Float" || n.class.name == "Rational"
+ end)
+ when :complex then @query.set_function(-> (n) {n.class.name == "Complex"})
+ end
+ end
+end
+
+class Filter
+ include BaseFilter
+
+ def initialize(&block)
+ @query = Query.new
+ @query.set_function(block)
+ end
+end
+
+class Query
+
+ def initialize
+ @add = true
+ end
+
+ def set_properties(first_query, second_query, is_add)
+ @first = first_query
+ @second = second_query
+ @add = is_add
+ end
+
+ def get_first
+ @first
+ end
+
+ def get_second
+ @second
+ end
+
+ def add?
+ @add
+ end
+
+ def set_function(function_to_set)
+ @function = function_to_set
+ end
+
+ def get_function
+ @function
+ end
+
+ def condition_satisfied?(n)
+ if get_function != nil
+ get_function.(n)
+ else
+ if add?
+ get_first.condition_satisfied?(n) && get_second.condition_satisfied?(n)
+ else
+ get_first.condition_satisfied?(n) || get_second.condition_satisfied?(n)
+ end
+ end
+ end
+end
Най-начално работещо решение, продължавам по него да го дооправям, но го пуснах и тук, за да ако не успея да го оправя, да не съм капо :)