Решение на Втора задача от Ясен Трифонов

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

Към профила на Ясен Трифонов

Резултати

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

Код

class NumberSet
include Enumerable
def initialize(numbers = [])
@numbers = numbers
end
def each(&block)
@numbers.each(&block)
end
def size
@numbers.size
end
def empty?
@numbers.empty?
end
def <<(number)
@numbers << number unless @numbers.include? number
end
def [](filter)
NumberSet.new @numbers.select { |number| filter.matches? number }
end
end
class Filter
def initialize(&block)
@predicate = block
end
def matches?(number)
@predicate.(number)
end
def |(other)
Filter.new { |number| matches?(number) || other.matches?(number) }
end
def &(other)
Filter.new { |number| matches?(number) && other.matches?(number) }
end
end
class TypeFilter < Filter
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 < Filter
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

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

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

Finished in 0.02211 seconds
24 examples, 0 failures

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

Ясен обнови решението на 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?, но различаваше типовете; сега като пробвам изглежда, че е наред, странно :)

Поздрави, Ясен.

Ясен обнови решението на 25.10.2014 01:08 (преди около 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
+ @numbers.empty?
end
def <<(number)
- @numbers << number unless @numbers.any? { |member| member == number }
+ @numbers << number unless @numbers.include? number
end
def [](filter)
NumberSet.new @numbers.select { |number| filter.matches? number }
end
end
-class Filterable
+class Filter
def initialize(&block)
@predicate = block
end
def matches?(number)
@predicate.(number)
end
def |(other)
- Filterable.new { |number| matches?(number) || other.matches?(number) }
+ Filter.new { |number| matches?(number) || other.matches?(number) }
end
def &(other)
- Filterable.new { |number| matches?(number) && other.matches?(number) }
+ Filter.new { |number| matches?(number) && other.matches?(number) }
end
end
-class Filter < Filterable
- def initialize(&block)
- super(&block)
- end
-end
-
-class TypeFilter < Filterable
+class TypeFilter < Filter
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
+class SignFilter < Filter
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