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

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

Към профила на Веселин Русинов

Резултати

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

Код

module BaseFilter
def &(other)
composition = FilterComposition.new(:&)
composition.filters << self
composition.filters << other
composition
end
def |(other)
composition = FilterComposition.new(:|)
composition.filters << self
composition.filters << other
composition
end
end
class FilterComposition
include BaseFilter
attr_accessor :filters
def initialize(type)
@type = type
@filters = []
end
def call(element)
case @type
when :&
and_option(element)
when :|
or_option(element)
end
end
def and_option(element)
@filters.each do |filter|
return false unless filter.call(element)
end
true
end
def or_option(element)
@filters.map do |filter|
return true if filter.call(element)
end
false
end
end
class Filter
def initialize(&block)
@block = block
end
def call(element)
@block.call(element)
end
end
class TypeFilter
include BaseFilter
def initialize(type)
types = [:integer, :real, :complex]
@type = type
end
def call(element)
case @type
when :integer then element.is_a? Integer
when :real then (element.is_a?(Float) || element.is_a?(Rational))
when :complex then element.is_a? Complex
end
end
end
class SignFilter
include BaseFilter
def initialize(type)
types = [:positive, :non_positive, :negative, :non_negative]
@type = type
end
def call(element)
case @type
when :positive then element > 0
when :non_positive then element <= 0
when :negative then element < 0
when :non_negative then element >= 0
end
end
end
class NumberSet
include Enumerable
def initialize(elements = [])
@container = elements
end
def [](filter)
NumberSet.new(@container.select{ |element| filter.call(element) })
end
def each(&block)
@container.each do |element|
if block_given?
block.call element
else
yield element
end
end
end
def <<(number)
if (number.is_a? Numeric) && !(@container.include?(number))
@container << number
end
end
def print
@container.each do |x|
puts x
end
end
def size
@container.length
end
def empty?
@container.length == 0
end
end

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

.................F.FFF.F

Failures:

  1) NumberSet can combine two filters with "or" rule
     Failure/Error: filter = Filter.new { |number| number % 2 == 0 } | Filter.new { |number| number > 5 }
     NoMethodError:
       undefined method `|' for #<Filter:0xba4cf404>
     # /tmp/d20141028-18133-1tvzmou/spec.rb:98:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) NumberSet can combine multiple filters with "or" rule
     Failure/Error: filter        = even | negative | more_than_100
     NoMethodError:
       undefined method `|' for #<Filter:0xba4cd474 @block=#<Proc:0xba4cd4b0>>
     # /tmp/d20141028-18133-1tvzmou/spec.rb:118:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) NumberSet can combine multiple filters with "and" and "or" rules
     Failure/Error: filter        = even & negative | mod_3_is_zero
     NoMethodError:
       undefined method `&' for #<Filter:0xba4cc920 @block=#<Proc:0xba4cd4b0>>
     # /tmp/d20141028-18133-1tvzmou/spec.rb:128:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) NumberSet can combine multiple filters with "and", "or" and parenthesis
     Failure/Error: filter        = even & (negative | mod_3_is_zero)
     NoMethodError:
       undefined method `&' for #<Filter:0xba593bc4 @block=#<Proc:0xba4cd4b0>>
     # /tmp/d20141028-18133-1tvzmou/spec.rb:138:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) NumberSet returns enumerable of set's contents if no block is given to each
     Failure/Error: expect(numbers.each.to_a.size).to eq [1, 3, 5].size
     LocalJumpError:
       no block given (yield)
     # /tmp/d20141028-18133-1tvzmou/solution.rb:123:in `block in each'
     # /tmp/d20141028-18133-1tvzmou/solution.rb:119:in `each'
     # /tmp/d20141028-18133-1tvzmou/solution.rb:119:in `each'
     # /tmp/d20141028-18133-1tvzmou/spec.rb:164:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.02178 seconds
24 examples, 5 failures

Failed examples:

rspec /tmp/d20141028-18133-1tvzmou/spec.rb:97 # NumberSet can combine two filters with "or" rule
rspec /tmp/d20141028-18133-1tvzmou/spec.rb:114 # NumberSet can combine multiple filters with "or" rule
rspec /tmp/d20141028-18133-1tvzmou/spec.rb:124 # NumberSet can combine multiple filters with "and" and "or" rules
rspec /tmp/d20141028-18133-1tvzmou/spec.rb:134 # NumberSet can combine multiple filters with "and", "or" and parenthesis
rspec /tmp/d20141028-18133-1tvzmou/spec.rb:159 # NumberSet returns enumerable of set's contents if no block is given to each

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

Веселин обнови решението на 27.10.2014 15:57 (преди около 10 години)

+module BaseFilter
+
+ def &(other)
+ composition = FilterComposition.new(:&)
+ composition.filters << self
+ composition.filters << other
+ composition
+ end
+
+ def |(other)
+ composition = FilterComposition.new(:|)
+ composition.filters << self
+ composition.filters << other
+ composition
+ end
+
+end
+
+class FilterComposition
+
+ include BaseFilter
+
+ attr_accessor :filters
+
+ def initialize(type)
+ @type = type
+ @filters = []
+ end
+
+ def call(element)
+ case @type
+ when :&
+ and_option(element)
+ when :|
+ or_option(element)
+ end
+ end
+
+ def and_option(element)
+ @filters.each do |filter|
+ return false unless filter.call(element)
+ end
+ true
+ end
+
+ def or_option(element)
+ @filters.map do |filter|
+ return true if filter.call(element)
+ end
+ false
+ end
+
+end
+
+class Filter
+
+ def initialize(&block)
+ @block = block
+ end
+
+ def call(element)
+ @block.call(element)
+ end
+
+end
+
+class TypeFilter
+
+ include BaseFilter
+
+ def initialize(type)
+ types = [:integer, :real, :complex]
+ @type = type
+ end
+
+ def call(element)
+ case @type
+ when :integer then element.is_a? Integer
+ when :real then (element.is_a?(Float) || element.is_a?(Rational))
+ when :complex then element.is_a? Complex
+ end
+ end
+
+end
+
+class SignFilter
+
+ include BaseFilter
+
+ def initialize(type)
+ types = [:positive, :non_positive, :negative, :non_negative]
+ @type = type
+ end
+
+ def call(element)
+ case @type
+ when :positive then element > 0
+ when :non_positive then element <= 0
+ when :negative then element < 0
+ when :non_negative then element >= 0
+ end
+ end
+
+end
+
+class NumberSet
+
+ include Enumerable
+
+ def initialize(elements = [])
+ @container = elements
+ end
+
+ def [](filter)
+ NumberSet.new(@container.select{ |element| filter.call(element) })
+ end
+
+ def each(&block)
+ @container.each do |element|
+ if block_given?
+ block.call element
+ else
+ yield element
+ end
+ end
+ end
+
+ def <<(number)
+ if (number.is_a? Numeric) && !(@container.include?(number))
+ @container << number
+ end
+ end
+
+ def print
+ @container.each do |x|
+ puts x
+ end
+ end
+
+ def size
+ @container.length
+ end
+
+ def empty?
+ @container.length == 0
+ end
+
+end