Решение на Втора задача от Светослав Кузманов

Обратно към всички решения

Към профила на Светослав Кузманов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 24 успешни тест(а)
  • 0 неуспешни тест(а)

Код

class NumberSet
include Enumerable
def initialize
@numbers = []
end
def <<(number)
@numbers << number unless @numbers.include? number
end
def size
@numbers.size
end
def empty?
@numbers.empty?
end
def each
if block_given?
@numbers.each { |e| yield(e) }
else
self.to_enum
end
end
def [](filter)
filtered_array = @numbers.select { |e| filter.filter(e) }
filtered_set = NumberSet.new
filtered_array.each { |e| filtered_set << e }
end
end
class Filter
def initialize(&block)
@block = block
end
def filter(number)
@block.(number)
end
def &(filter)
FilterIntersection.new self, filter
end
def |(filter)
FilterUnion.new self, filter
end
end
class TypeFilter < Filter
def initialize(type)
@type = type
end
def filter(number)
case @type
when :integer then number.is_a? Integer
when :real then number.is_a? Float or number.is_a? Rational
when :complex then number.is_a? Complex
end
end
end
class SignFilter < Filter
def initialize(sign)
@sign = sign
end
def filter(number)
case @sign
when :positive then number > 0
when :non_positive then number <= 0
when :negative then number < 0
when :non_negative then number >= 0
end
end
end
class FilterIntersection < Filter
def initialize(first_filter, second_filter)
@first_filter = first_filter
@second_filter = second_filter
end
def filter(number)
@second_filter.filter(number) and @first_filter.filter(number)
end
end
class FilterUnion < Filter
def initialize(first_filter, second_filter)
@first_filter = first_filter
@second_filter = second_filter
end
def filter(number)
@second_filter.filter(number) or @first_filter.filter(number)
end
end

Лог от изпълнението

........................

Finished in 0.02198 seconds
24 examples, 0 failures

История (2 версии и 1 коментар)

Светослав обнови решението на 25.10.2014 18:06 (преди над 9 години)

+module Operators
+ def &(filter)
+ FilterIntersection.new self, filter
+ end
+
+ def |(filter)
+ FilterUnion.new self, filter
+ end
+end
+
+class NumberSet
+ include Enumerable
+
+ def initialize()
+ @numbers = []
+ end
+
+ def <<(number)
+ @numbers << number unless @numbers.include? number
+ end
+
+ def size
+ @numbers.size
+ end
+
+ def empty?
+ @numbers.empty?
+ end
+
+ def each
+ @numbers.each { |e| yield(e) }
+ end
+
+ def [](filter)
+ @numbers.select { |e| filter.filter(e) }
+ end
+end
+
+class Filter
+ include Operators
+
+ def initialize(&block)
+ @block = block
+ end
+
+ def filter(number)
+ @block.(number)
+ end
+end
+
+class TypeFilter
+ include Operators
+
+ def initialize(type)
+ @type = type
+ end
+
+ def filter(number)
+ case @type
+ when :integer then number.is_a? Integer
+ when :real then number.is_a? Float or number.is_a? Rational
+ when :complex then number.is_a? Complex
+ end
+ end
+end
+
+class SignFilter
+ include Operators
+
+ def initialize(sign)
+ @sign = sign
+ end
+
+ def filter(number)
+ case @sign
+ when :positive then number > 0
+ when :non_positive then number <= 0
+ when :negative then number < 0
+ when :non_negative then number >= 0
+ end
+ end
+end
+
+class FilterIntersection
+ include Operators
+
+ def initialize(first_filter, second_filter)
+ @first_filter = first_filter
+ @second_filter = second_filter
+ end
+
+ def filter(number)
+ @second_filter.filter(number) and @first_filter.filter(number)
+ end
+end
+
+class FilterUnion
+ include Operators
+
+ def initialize(first_filter, second_filter)
+ @first_filter = first_filter
+ @second_filter = second_filter
+ end
+
+ def filter(number)
+ @second_filter.filter(number) or @first_filter.filter(number)
+ end
+end

Здрасти,

Хубаво решение. Ето няколко препоръки:

  • Защо избра да ползваш mixin? Не можеше ли да минеш без Operators и да оставиш TypeFilter, SignFIlter, ... да наследят Filter, където да имплементираш двата метода?
  • Не слагай скоби при дефиниране на метод, ако той няма параметри.
  • Мисля си, че в NumberSet#[] връщаш Array обект, а ние очакваме NumberSet обратно. Кода в метода ти не е идентиран правилно.
  • Провери как работи Array#each, когато не му подадеш блок. Очакваме NumberSet#each да се държи по същия начин.
  • Аз бих подравнил then-овете в двата case-а. Ще стане много красиво, обещавам. :))

Светослав обнови решението на 26.10.2014 21:39 (преди над 9 години)

-module Operators
- def &(filter)
- FilterIntersection.new self, filter
- end
-
- def |(filter)
- FilterUnion.new self, filter
- end
-end
-
class NumberSet
include Enumerable
- def initialize()
+ def initialize
@numbers = []
end
def <<(number)
@numbers << number unless @numbers.include? number
end
def size
@numbers.size
end
def empty?
@numbers.empty?
end
def each
- @numbers.each { |e| yield(e) }
+ if block_given?
+ @numbers.each { |e| yield(e) }
+ else
+ self.to_enum
+ end
end
def [](filter)
- @numbers.select { |e| filter.filter(e) }
+ filtered_array = @numbers.select { |e| filter.filter(e) }
+ filtered_set = NumberSet.new
+ filtered_array.each { |e| filtered_set << e }
end
end
class Filter
- include Operators
-
def initialize(&block)
- @block = block
+ @block = block
end
def filter(number)
@block.(number)
end
-end
-class TypeFilter
- include Operators
+ def &(filter)
+ FilterIntersection.new self, filter
+ end
+ def |(filter)
+ FilterUnion.new self, filter
+ end
+end
+
+class TypeFilter < Filter
def initialize(type)
@type = type
end
def filter(number)
case @type
when :integer then number.is_a? Integer
- when :real then number.is_a? Float or number.is_a? Rational
+ when :real then number.is_a? Float or number.is_a? Rational
when :complex then number.is_a? Complex
end
end
end
-class SignFilter
- include Operators
-
+class SignFilter < Filter
def initialize(sign)
@sign = sign
end
def filter(number)
case @sign
- when :positive then number > 0
+ when :positive then number > 0
when :non_positive then number <= 0
- when :negative then number < 0
+ when :negative then number < 0
when :non_negative then number >= 0
end
end
end
-class FilterIntersection
- include Operators
-
+class FilterIntersection < Filter
def initialize(first_filter, second_filter)
@first_filter = first_filter
@second_filter = second_filter
end
def filter(number)
@second_filter.filter(number) and @first_filter.filter(number)
end
end
-class FilterUnion
- include Operators
-
+class FilterUnion < Filter
def initialize(first_filter, second_filter)
@first_filter = first_filter
@second_filter = second_filter
end
def filter(number)
@second_filter.filter(number) or @first_filter.filter(number)
end
end