Евгений обнови решението на 27.10.2014 15:25 (преди около 10 години)
+require 'set'
+
+class NumberSet
+
+ include Enumerable
+
+ def initialize()
+ @numbers = Set.new
+ end
+
+ def <<(n)
+ @numbers.each do |number|
+ if number == n
+ return
+ end
+ end
+ @numbers << n
+ self
+ end
+
+ def each
+ if block_given?
+ @numbers.each { |e| yield(e) }
+ end
+ end
+
+ def [](filter)
+ filter.call(@numbers)
+ end
+
+ def size
+ return @numbers.size
+ end
+
+ def empty?
+ @numbers.empty?
+ end
+
+ def to_a
+ @numbers.to_a
+ end
+
+ def self.from_s(set)
+ new_numbers = NumberSet.new
+ set.each do |number|
+ new_numbers << number
+ end
+ return new_numbers
+ end
+
+end
+
+class Command
+ def execute()
+
+ end
+end
+
+class BaseFilter < Command
+ def initialize()
+ @filters = Array.new
+ end
+
+ def execute(numbers, new_numbers)
+ set = Set.new(new_numbers.to_a)
+ return self.call(set)
+ end
+
+ def call(numbers)
+ new_numbers = NumberSet.from_s(numbers)
+ while not @filters.empty? do
+ command = @filters.shift
+ new_numbers = command.execute(numbers, new_numbers)
+ if not new_numbers.empty?
+ return new_numbers
+ end
+ end
+ return new_numbers
+ end
+ def add(filter)
+ @filters.push(filter)
+ end
+ def &(filter)
+ new_filter = BaseFilter.new
+ new_filter.add(self)
+ new_filter.add(AndOperation.new)
+ new_filter.add(filter)
+ return new_filter
+ end
+
+ def |(filter)
+ new_filter = BaseFilter.new
+ new_filter.add(self)
+ new_filter.add(OrOperation.new)
+ new_filter.add(filter)
+ return new_filter
+ end
+
+end
+
+class Operation < Command
+
+ def execute(numbers, new_numbers)
+ return self.call(numbers, new_numbers)
+ end
+
+end
+
+class OrOperation < Operation
+
+ def call(numbers, new_numbers)
+ if new_numbers.empty?
+ return NumberSet.from_s(numbers)
+ else
+ return new_numbers
+ end
+ end
+end
+class AndOperation < Operation
+ def call(numbers, new_numbers)
+ return new_numbers
+ end
+end
+class Filter < BaseFilter
+ def initialize(&block)
+ @block = block
+ end
+ def call(numbers)
+ new_numbers = NumberSet.new
+ numbers.each do |n|
+ if @block.call(n)
+ new_numbers << n
+ end
+ end
+ return new_numbers
+ end
+end
+class SignFilter < BaseFilter
+ def initialize(type)
+ @type = type
+ end
+ def call(numbers)
+ new_numbers = NumberSet.new
+ case @type
+ when :positive then get_positive(numbers, new_numbers)
+ when :negative then get_negative(numbers, new_numbers)
+ when :non_positive then get_non_positive(numbers, new_numbers)
+ when :non_negative then get_non_negative(numbers, new_numbers)
+ end
+ return new_numbers
+ end
+ def get_positive(numbers, new_numbers)
+ numbers.each do |n|
+ if n > 0
+ new_numbers << n
+ end
+ end
+ end
+ def get_negative(numbers, new_numbers)
+ numbers.each do |n|
+ if n < 0
+ new_numbers << n
+ end
+ end
+ end
+ def get_non_positive(numbers, new_numbers)
+ numbers.each do |n|
+ if n <= 0
+ new_numbers << n
+ end
+ end
+ end
+ def get_non_negative(numbers, new_numbers)
+ numbers.each do |n|
+ if n >= 0
+ new_numbers << n
+ end
+ end
+ end
+end