Ясен обнови решението на 25.10.2014 00:14 (преди около 10 години)
+class NumberSet
+ include Enumerable
+
+ attr_reader :numbers
+
+ def initialize(numbers = [])
+ @numbers = numbers
+ end
+
+ def each(&block)
+ @numbers.each(&block)
+ end
+
+ def size
+ @numbers.size
+ end
+
+ def empty?
+ @numbers.size == 0
+ end
+
+ def <<(number)
+ @numbers << number unless @numbers.any? { |member| member == number }
+ end
+
+ def [](filter)
+ NumberSet.new @numbers.select { |number| filter.matches? number }
+ end
+end
+
+class Filterable
+ def initialize(&block)
+ @predicate = block
+ end
+
+ def matches?(number)
+ @predicate.(number)
+ end
+
+ def |(other)
+ Filterable.new { |number| matches?(number) || other.matches?(number) }
+ end
+
+ def &(other)
+ Filterable.new { |number| matches?(number) && other.matches?(number) }
+ end
+end
+
+class Filter < Filterable
+ def initialize(&block)
+ super(&block)
+ end
+end
+
+class TypeFilter < Filterable
+ def initialize(type)
+ case type
+ when :integer then super() { |number| number.kind_of? Integer }
+ when :real then super() { |number| number.is_a?(Float) ||
+ number.is_a?(Rational) }
+ when :complex then super() { |number| number.is_a? Complex }
+ end
+ end
+end
+
+class SignFilter < Filterable
+ def initialize(sign)
+ case sign
+ when :positive then super() { |number| number > 0 }
+ when :negative then super() { |number| number < 0 }
+ when :non_positive then super() { |number| number <= 0 }
+ when :non_negative then super() { |number| number >= 0 }
+ end
+ end
+end
Здрасти,
Много, много добро решение. Имам само няколко предложения:
- Не ти трябва reader за
@numbers
-
@numbers.any? { |member| member == number }
е еквивалентно на@numbers.include? number
-
empty?
също можеш да го делегираш наArray
. Подобно наsize
. - Защо ти е
Filterable
. Според мен можеш да го слееш сFilter
. Името не е много коректно също така. "Filterable" очаквам да е нещо, което може да бъде филтрирано. ПримерноNumberSet
. - Можеш да подравниш
number.is_a?...
частта при:real
случая вcase
-а.
Здрасти,
Благодаря за предложенията, всяко от тях е доста полезно! Особено не се бях замислял, че Filter реално може да свърши работата на Filterable
(спрямо означенията в кода).
number.is_a?
покрай real
излиза подравнено локално във vim
, интересно (забелязах го, но не ми се submit-ваше нова версия само заради това). Сигурен съм, че пробвах и include?
, но различаваше типовете; сега като пробвам изглежда, че е наред, странно :)
Поздрави, Ясен.