Решение на Втора задача от Александър Петков

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

Към профила на Александър Петков

Резултати

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

Код

require 'set'
class NumberSet
include Enumerable
def initialize
@numbers = Set.new
end
def << (number)
unless @numbers.any? { |element| element == number }
@numbers << number
end
self
end
def empty?
@numbers.empty?
end
def size
@numbers.size
end
def each
return to_enum(:each) unless block_given?
@numbers.each { |element| yield element }
end
def [](filter)
@numbers.each_with_object(NumberSet.new) do |number, new_set|
new_set << number if filter.satisfies?(number)
end
end
end
module NumbersFilter
def satisfies?(number)
@condition.call number
end
def &(filter)
Filter.new do |number|
self.satisfies?(number) && filter.satisfies?(number)
end
end
def |(filter)
Filter.new do |number|
self.satisfies?(number) || filter.satisfies?(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

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

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

Finished in 0.02503 seconds
24 examples, 0 failures

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

Александър обнови решението на 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 за консистентност с другия филтър.

Александър обнови решението на 26.10.2014 12:50 (преди около 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
+ return to_enum(:each) unless block_given?
@numbers.each { |element| yield element }
end
def [](filter)
filtered = NumberSet.new
- @numbers.select { |element| filter.includes(element) }.each do |number|
+ @numbers.select { |element| filter.satisfies?(element) }.each do |number|
filtered << number
end
filtered
end
end
module NumbersFilter
- attr_accessor :condition
-
- def includes(number)
+ def satisfies?(number)
@condition.call number
end
def &(filter)
Filter.new do |number|
- filter.condition.call(number) && @condition.call(number)
+ filter.satisfies?(number) && @condition.call(number)
end
end
def |(filter)
Filter.new do |number|
- filter.condition.call(number) || @condition.call(number)
+ filter.satisfies?(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

Александър обнови решението на 26.10.2014 12:56 (преди около 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
return to_enum(:each) unless block_given?
@numbers.each { |element| yield element }
end
def [](filter)
- filtered = NumberSet.new
- @numbers.select { |element| filter.satisfies?(element) }.each do |number|
- filtered << number
+ @numbers.each_with_object(NumberSet.new) do |number, new_set|
+ new_set << number if filter.satisfies?(number)
end
- filtered
end
end
module NumbersFilter
def satisfies?(number)
@condition.call number
end
def &(filter)
Filter.new do |number|
filter.satisfies?(number) && @condition.call(number)
end
end
def |(filter)
Filter.new do |number|
filter.satisfies?(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

Александър обнови решението на 26.10.2014 13:00 (преди около 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
return to_enum(:each) unless block_given?
@numbers.each { |element| yield element }
end
def [](filter)
@numbers.each_with_object(NumberSet.new) do |number, new_set|
new_set << number if filter.satisfies?(number)
end
end
end
module NumbersFilter
def satisfies?(number)
@condition.call number
end
def &(filter)
Filter.new do |number|
- filter.satisfies?(number) && @condition.call(number)
+ self.satisfies?(number) && filter.satisfies?(number)
end
end
def |(filter)
Filter.new do |number|
- filter.satisfies?(number) || @condition.call(number)
+ self.satisfies?(number) || filter.satisfies?(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

Здрасти и мерси за коментарите :) Бърз follow-up:

  • доколкото видях @numbers.any? { |element| element == number } в случая не е еквивалентно на @numbers.include? number, понеже при set проверката за еднаквост изисква Object#eql? и Object#hash, вместо ==
  • в SignFiltercase излиза на 9 реда, затова са тия if-ове :) може би да променя и TypeFilter така?
  • трябва ли да връщаме self при оператора <<, ще тествате ли нещо като set << 1 << 2 << 3 ...?

Александър обнови решението на 26.10.2014 14:12 (преди около 10 години)

require 'set'
class NumberSet
include Enumerable
def initialize
@numbers = Set.new
end
def << (number)
unless @numbers.any? { |element| element == number }
@numbers << number
end
+ self
end
def empty?
@numbers.empty?
end
def size
@numbers.size
end
def each
return to_enum(:each) unless block_given?
@numbers.each { |element| yield element }
end
def [](filter)
@numbers.each_with_object(NumberSet.new) do |number, new_set|
new_set << number if filter.satisfies?(number)
end
end
end
module NumbersFilter
def satisfies?(number)
@condition.call number
end
def &(filter)
Filter.new do |number|
self.satisfies?(number) && filter.satisfies?(number)
end
end
def |(filter)
Filter.new do |number|
self.satisfies?(number) || filter.satisfies?(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