Александър обнови решението на 26.10.2014 03:30 (преди около 10 години)
+require 'set'
+
+class NumberSet
+ include Enumerable
+
+ def initialize
+ @numbers = Set.new
+ end
+
+ def << (number)
+ unless @numbers.any? { |element| element == number }
+ @numbers << number
+ end
+ end
+
+ def empty?
+ @numbers.empty?
+ end
+
+ def size
+ @numbers.size
+ end
+
+ def each
+ @numbers.each { |element| yield element }
+ end
+
+ def [](filter)
+ filtered = NumberSet.new
+ @numbers.select { |element| filter.includes(element) }.each do |number|
+ filtered << number
+ end
+ filtered
+ end
+end
+
+module NumbersFilter
+ attr_accessor :condition
+
+ def includes(number)
+ @condition.call number
+ end
+
+ def &(filter)
+ Filter.new do |number|
+ filter.condition.call(number) && @condition.call(number)
+ end
+ end
+
+ def |(filter)
+ Filter.new do |number|
+ filter.condition.call(number) || @condition.call(number)
+ end
+ end
+end
+
+class Filter
+ include NumbersFilter
+
+ def initialize(&condition)
+ @condition = condition
+ end
+end
+
+class TypeFilter
+ include NumbersFilter
+
+ def initialize(type)
+ case type
+ when :integer
+ @condition = proc { |n| n.integer? }
+ when :real
+ @condition = proc { |n| n.class == Float || n.class == Rational }
+ when :complex
+ @condition = proc { |n| n.class == Complex }
+ end
+ end
+end
+
+class SignFilter
+ include NumbersFilter
+
+ def initialize(condition)
+ if condition == :positive
+ @condition = proc { |element| element > 0 }
+ elsif condition == :non_positive
+ @condition = proc { |element| element <= 0 }
+ elsif condition == :negative
+ @condition = proc { |element| element < 0 }
+ elsif condition == :non_negative
+ @condition = proc { |element| element >= 0 }
+ end
+ end
+end
Здрасти,
Ето няколко неща от мен:
-
@numbers.any? { |element| element == number }
е по-дългия вариант за@numbers.include? number
- Провери как работи
Array#each
, когато не му подадеш блок. Очакваме същото отNumberSet#each
. - Хвърли око на
Enumerable#each_with_object
. -
attr_accessor
-и не ти трябва. Имаш методаincludes
, на който би трябвало да му измислиш по-добро име. Имаме конвенция за методи, които връщат булева стойност. - Ползвай
case
вSignFilter
за консистентност с другия филтър.