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

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

Към профила на Константин Тодоров

Резултати

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

Код

class NumberSet
include Enumerable
def initialize(given_numbers = [])
@numbers = given_numbers
end
def <<(number)
@numbers << number unless @numbers.include?(number)
end
def size
@numbers.length
end
def empty?
@numbers.empty?
end
def [](filter)
temp_numbers = []
@numbers.select do |number|
temp_numbers << number if filter.passes(number)
end
NumberSet.new(temp_numbers)
end
def each
return @numbers.to_enum unless block_given?
@numbers.each do |number|
yield number
end
end
end
class Filter
def initialize(&given_filter)
@filter = given_filter
end
def filtrate(number)
@filter.call(number)
end
def &(other)
Filter.new { |x| filtrate(x) && other.filtrate(x) }
end
def |(other)
Filter.new { |x| filtrate(x) || other.filtrate(x) }
end
alias :passes :filtrate
end
class TypeFilter < Filter
def initialize(type)
case type
when :integer then super() { |n| n.is_a? Integer }
when :real then super() { |n| n.is_a? Float or n.is_a? Rational }
when :complex then super() { |n| n.is_a? Complex }
end
end
end
class SignFilter < Filter
def initialize(selection)
case selection
when :positive then super() { |n| n > 0 }
when :non_negative then super() { |n| n >= 0 }
when :negative then super() { |n| n < 0 }
when :non_positive then super() { |n| n <= 0 }
end
end
end

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

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

Finished in 0.02248 seconds
24 examples, 0 failures

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

Константин обнови решението на 24.10.2014 01:15 (преди около 10 години)

+class NumberSet
+ include Enumerable
+
+ def initialize
+ @numbers = []
+ end
+
+ def <<(number)
+ unless @numbers.include?(number)
+ @numbers << number
+ end
+ end
+
+ def size
+ @numbers.length
+ end
+
+ def empty?
+ self.size == 0
+ end
+
+ def [](other)
+ @numbers.select do |number|
+ number if other.filter.call(number)
+ end
+ end
+
+ def each
+ @numbers.each do |number|
+ number if yield number
+ end
+ end
+end
+
+class Filter
+ attr_accessor :filter
+
+ def initialize(&given_filter)
+ @filter = given_filter
+ end
+
+ def &(other)
+ Filter.new { |x| filter.call(x) && other.filter.call(x) }
+ end
+
+ def |(other)
+ Filter.new { |x| filter.call(x) || other.filter.call(x) }
+ end
+end
+
+class TypeFilter < Filter
+ def initialize type
+ case type
+ when :integer then @filter = get_integer_filter()
+ when :real then @filter = get_real_filter()
+ when :complex then @filter = get_complex_filter()
+ end
+ end
+
+ def get_integer_filter
+ Proc.new { |n| n if n.is_a? Integer }
+ end
+
+ def get_complex_filter
+ Proc.new { |n| n if n.is_a? Complex }
+ end
+
+ def get_real_filter
+ Proc.new { |n| n if n.is_a? Float or n.is_a? Rational}
+ end
+
+ def get_lambda type
+ check = lambda { |n| n if n.is_a? Integer}
+ end
+end
+
+class SignFilter < Filter
+ def initialize selection
+ case selection
+ when :positive then @filter = get_positive_filter(false)
+ when :non_negative then @filter = get_positive_filter(true)
+ when :negative then @filter = get_negative_filter(false)
+ when :non_positive then @filter = get_negative_filter(true)
+ end
+ end
+
+ def get_positive_filter include_zero
+ Proc.new { |n| n if n > 0 || (include_zero && n == 0) }
+ end
+
+ def get_negative_filter include_zero
+ Proc.new { |n| n if n < 0 || (include_zero && n == 0) }
+ end
+end

Константин обнови решението на 24.10.2014 01:17 (преди около 10 години)

class NumberSet
include Enumerable
def initialize
@numbers = []
end
def <<(number)
- unless @numbers.include?(number)
- @numbers << number
+ unless @numbers.include?(number)
+ @numbers << number
end
end
def size
@numbers.length
end
def empty?
self.size == 0
end
def [](other)
@numbers.select do |number|
number if other.filter.call(number)
end
end
def each
@numbers.each do |number|
number if yield number
end
end
end
class Filter
attr_accessor :filter
def initialize(&given_filter)
@filter = given_filter
end
def &(other)
Filter.new { |x| filter.call(x) && other.filter.call(x) }
end
def |(other)
Filter.new { |x| filter.call(x) || other.filter.call(x) }
end
end
class TypeFilter < Filter
def initialize type
case type
- when :integer then @filter = get_integer_filter()
+ when :integer then @filter = get_integer_filter()
when :real then @filter = get_real_filter()
when :complex then @filter = get_complex_filter()
end
end
def get_integer_filter
- Proc.new { |n| n if n.is_a? Integer }
+ Proc.new { |n| n if n.is_a? Integer }
end
def get_complex_filter
Proc.new { |n| n if n.is_a? Complex }
end
def get_real_filter
Proc.new { |n| n if n.is_a? Float or n.is_a? Rational}
end
def get_lambda type
check = lambda { |n| n if n.is_a? Integer}
end
end
class SignFilter < Filter
def initialize selection
- case selection
- when :positive then @filter = get_positive_filter(false)
+ case selection
+ when :positive then @filter = get_positive_filter(false)
when :non_negative then @filter = get_positive_filter(true)
when :negative then @filter = get_negative_filter(false)
when :non_positive then @filter = get_negative_filter(true)
- end
+ end
end
def get_positive_filter include_zero
Proc.new { |n| n if n > 0 || (include_zero && n == 0) }
end
def get_negative_filter include_zero
Proc.new { |n| n if n < 0 || (include_zero && n == 0) }
end
end

Здрасти,

Решението ти ми харесва. Имам няколко забележки, върху които можеш да помислиш:

  • Слагай скоби около параметрите при дефиниция на метод, ако такива има.
  • self.size == 0 можеш да запишеш като size == 0 или като @numbers.empty?.
  • Enumerable#select работи така, че ползва блока, който му подаваш само като условие. Тоест, блока който подаваш трябва да се оценя до истина или лъжа. В контекста на твоя NumberSet#[], number if other.filter.call(number) трябва да запишеш като other.filter.call(number).
  • Провери как работи Array#each, ако не му подадеш блок. Очакваме NumberSet#each да се държи по същия начин.
  • Защо вместо attr_accessor-а във Filter не си направиш един метод, който приема число и връща дали това число минава филтъра. Според мен това ще улесни използването на класа ти и ще скрие имплементацията му.
  • get_lambda метода не ми се връзва изобщо.
  • Според мен си отишъл твърде далеч в SignFilter. Мисля, че ще е по-просто, ако оставиш само initialize метода там и разпишеш условията направо в case-a. Също така, вместо да даваш стойност на магическото поле @filter, можеш да ползваш super и да подадеш блок на конструктора на Filter: super() { |number| ... }. Ще се държи по същия начин.

Константин обнови решението на 26.10.2014 20:35 (преди около 10 години)

class NumberSet
include Enumerable
- def initialize
- @numbers = []
+ def initialize(given_numbers = [])
+ @numbers = given_numbers
end
def <<(number)
- unless @numbers.include?(number)
- @numbers << number
- end
+ @numbers << number unless @numbers.include?(number)
end
def size
@numbers.length
end
def empty?
- self.size == 0
+ @numbers.empty?
end
- def [](other)
+ def [](filter)
+ temp_numbers = []
@numbers.select do |number|
- number if other.filter.call(number)
+ temp_numbers << number if filter.passes(number)
end
+ NumberSet.new(temp_numbers)
end
def each
+ return @numbers.to_enum unless block_given?
@numbers.each do |number|
- number if yield number
+ yield number
end
end
end
class Filter
- attr_accessor :filter
-
def initialize(&given_filter)
@filter = given_filter
end
+ def filtrate(number)
+ @filter.call(number)
+ end
+
def &(other)
- Filter.new { |x| filter.call(x) && other.filter.call(x) }
+ Filter.new { |x| filtrate(x) && other.filtrate(x) }
end
def |(other)
- Filter.new { |x| filter.call(x) || other.filter.call(x) }
+ Filter.new { |x| filtrate(x) || other.filtrate(x) }
end
+
+ alias :passes :filtrate
end
class TypeFilter < Filter
- def initialize type
+ def initialize(type)
case type
- when :integer then @filter = get_integer_filter()
- when :real then @filter = get_real_filter()
- when :complex then @filter = get_complex_filter()
+ when :integer then super() { |n| n.is_a? Integer }
+ when :real then super() { |n| n.is_a? Float or n.is_a? Rational }
+ when :complex then super() { |n| n.is_a? Complex }
end
end
-
- def get_integer_filter
- Proc.new { |n| n if n.is_a? Integer }
- end
-
- def get_complex_filter
- Proc.new { |n| n if n.is_a? Complex }
- end
-
- def get_real_filter
- Proc.new { |n| n if n.is_a? Float or n.is_a? Rational}
- end
-
- def get_lambda type
- check = lambda { |n| n if n.is_a? Integer}
- end
end
class SignFilter < Filter
- def initialize selection
+ def initialize(selection)
case selection
- when :positive then @filter = get_positive_filter(false)
- when :non_negative then @filter = get_positive_filter(true)
- when :negative then @filter = get_negative_filter(false)
- when :non_positive then @filter = get_negative_filter(true)
+ when :positive then super() { |n| n > 0 }
+ when :non_negative then super() { |n| n >= 0 }
+ when :negative then super() { |n| n < 0 }
+ when :non_positive then super() { |n| n <= 0 }
end
- end
-
- def get_positive_filter include_zero
- Proc.new { |n| n if n > 0 || (include_zero && n == 0) }
- end
-
- def get_negative_filter include_zero
- Proc.new { |n| n if n < 0 || (include_zero && n == 0) }
end
end