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

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

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

Резултати

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

Код

class Collection < Array
def self.parse(raw_data)
collection = Collection.new
raw_data.lines.map(&:chomp).each_slice(4) do |lines|
collection.push Song.new lines[0], lines[1], lines[2]
end
collection
end
def artists
map(&:artist).uniq
end
def names
map(&:name).uniq
end
def albums
map(&:album).uniq
end
def filter(expression)
Collection.new(select { |song| expression.match? song })
end
def adjoin(other)
result = Collection.new self
result.concat other
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
attr_accessor :type, :value
attr_writer :positive
def initialize(type, value, positive = true)
@type = type
@value = value
@positive = positive
end
def positive?
@positive
end
def self.name(value)
Expression.new :and, Criteria.new(:name, value)
end
def self.artist(value)
Expression.new :and, Criteria.new(:artist, value)
end
def self.album(value)
Expression.new :and, Criteria.new(:album, value)
end
def !()
Criteria.new @type, @value, !positive?
end
def match?(song)
song.send(@type) == @value
end
end
class Expression
attr_accessor :type, :variables
def initialize(type, variables)
@type = type
@variables = variables
end
def &(other)
if other.type == @type and @type == :and
Expression.new :and, [@variables, other.variables].flatten
else
Expression.new :and, [self, other]
end
end
def |(other)
if other.type == @type and @type == :or
Expression.new :or, [@variables, other.variables].flatten
else
Expression.new :or, [self, other]
end
end
def !()
new_type = @type == :and ? :or : :and
Expression.new new_type, @variables.map { |variable| !variable }
end
def match?(thing)
return @variables.match? thing if @variables.respond_to?(:match?)
if @type == :and
match_all_variables? thing
else
match_any_variable? thing
end
end
private
def match_all_variables? thing
@variables.all? { |variable| variable.match? thing }
end
def match_any_variable? thing
@variables.any? { |variable| variable.match? thing }
end
end

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

.........F.

Failures:

  1) Collection supports negation of filters
     Failure/Error: filtered = collection.filter Criteria.artist('Sting') & !Criteria.name('Fields of Gold')
     NoMethodError:
       undefined method `map' for #<Criteria:0xa8afe1c>
     # /tmp/d20130203-23049-hmsazw/solution.rb:102:in `!'
     # /tmp/d20130203-23049-hmsazw/spec.rb:78:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.0108 seconds
11 examples, 1 failure

Failed examples:

rspec /tmp/d20130203-23049-hmsazw/spec.rb:77 # Collection supports negation of filters

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

Александър обнови решението на 31.10.2012 02:09 (преди над 11 години)

+class Collection < Array
+ def self.parse(raw_data)
+ collection = Collection.new
+ raw_data.lines.map(&:chomp).each_slice(4) do |lines|
+ collection.push Song.new lines[0], lines[1], lines[2]
+ end
+ collection
+ end
+
+ def artists
+ map(&:artist).uniq
+ end
+
+ def names
+ map(&:name).uniq
+ end
+
+ def albums
+ map(&:album).uniq
+ end
+
+ def filter(expression)
+ Collection.new(select { |song| expression.match song })
+ end
+
+ def adjoin(other)
+ result = Collection.new self
+ result.concat other
+ end
+end
+
+class Song
+ attr_accessor :name, :artist, :album
+
+ def initialize(name, artist, album)
+ @name, @artist, @album = name, artist, album
+ end
+end
+
+class Criteria
+ attr_accessor :type, :value
+
+ attr_writer :positive
+
+ def initialize(type, value, positive = true)
+ @type = type
+ @value = value
+ @positive = positive
+ end
+
+ def positive?
+ @positive
+ end
+
+ def self.name(value)
+ Expression.new :and, Criteria.new(:name, value)
+ end
+
+ def self.artist(value)
+ Expression.new :and, Criteria.new(:artist, value)
+ end
+
+ def self.album(value)
+ Expression.new :and, Criteria.new(:album, value)
+ end
+
+ def !()
+ Criteria.new @type, @value, !positive?
+ end
+
+ def match(song)
+ song.send(@type) == @value
+ end
+end
+
+class Expression
+ attr_accessor :type, :variables
+
+ def initialize(type, variables = [])
+ @type = type
+ @variables = variables
+ end
+
+ def &(other)
+ if other.type == @type and @type == :and
+ Expression.new :and, [@variables, other.variables].flatten
+ else
+ Expression.new :and, [self, other]
+ end
+ end
+
+ def |(other)
+ if other.type == @type and @type == :or
+ Expression.new :or, [@variables, other.variables].flatten
+ else
+ Expression.new :or, [self, other]
+ end
+ end
+
+ def !()
+ new_type = @type == :and ? :or : :and
+ Expression.new new_type, @variables.map { |variable| !variable }
+ end
+
+ def match(thing)
+ return @variables.match thing if @variables.respond_to?(:match)
+
+ if @type == :and
+ _match_all_variables thing
+ else
+ _match_at_least_one_variable thing
+ end
+ end
+
+ def _match_all_variables thing
+ @variables.all? { |variable| variable.match thing }
+ end
+
+ def _match_at_least_one_variable thing
+ @variables.any? { |variable| variable.match thing }
+ end
+end

Александър обнови решението на 31.10.2012 02:12 (преди над 11 години)

class Collection < Array
def self.parse(raw_data)
collection = Collection.new
raw_data.lines.map(&:chomp).each_slice(4) do |lines|
collection.push Song.new lines[0], lines[1], lines[2]
end
collection
end
def artists
map(&:artist).uniq
end
def names
map(&:name).uniq
end
def albums
map(&:album).uniq
end
def filter(expression)
Collection.new(select { |song| expression.match song })
end
def adjoin(other)
result = Collection.new self
result.concat other
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
attr_accessor :type, :value
attr_writer :positive
def initialize(type, value, positive = true)
@type = type
@value = value
@positive = positive
end
def positive?
@positive
end
def self.name(value)
Expression.new :and, Criteria.new(:name, value)
end
def self.artist(value)
Expression.new :and, Criteria.new(:artist, value)
end
def self.album(value)
Expression.new :and, Criteria.new(:album, value)
end
def !()
Criteria.new @type, @value, !positive?
end
def match(song)
song.send(@type) == @value
end
end
class Expression
attr_accessor :type, :variables
- def initialize(type, variables = [])
+ def initialize(type, variables)
@type = type
@variables = variables
end
def &(other)
if other.type == @type and @type == :and
Expression.new :and, [@variables, other.variables].flatten
else
Expression.new :and, [self, other]
end
end
def |(other)
if other.type == @type and @type == :or
Expression.new :or, [@variables, other.variables].flatten
else
Expression.new :or, [self, other]
end
end
def !()
new_type = @type == :and ? :or : :and
Expression.new new_type, @variables.map { |variable| !variable }
end
def match(thing)
return @variables.match thing if @variables.respond_to?(:match)
if @type == :and
_match_all_variables thing
else
_match_at_least_one_variable thing
end
end
def _match_all_variables thing
@variables.all? { |variable| variable.match thing }
end
def _match_at_least_one_variable thing
@variables.any? { |variable| variable.match thing }
end
end

Александър обнови решението на 31.10.2012 10:45 (преди над 11 години)

class Collection < Array
def self.parse(raw_data)
collection = Collection.new
raw_data.lines.map(&:chomp).each_slice(4) do |lines|
collection.push Song.new lines[0], lines[1], lines[2]
end
collection
end
def artists
map(&:artist).uniq
end
def names
map(&:name).uniq
end
def albums
map(&:album).uniq
end
def filter(expression)
- Collection.new(select { |song| expression.match song })
+ Collection.new(select { |song| expression.match? song })
end
def adjoin(other)
result = Collection.new self
result.concat other
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
attr_accessor :type, :value
attr_writer :positive
def initialize(type, value, positive = true)
@type = type
@value = value
@positive = positive
end
def positive?
@positive
end
def self.name(value)
Expression.new :and, Criteria.new(:name, value)
end
def self.artist(value)
Expression.new :and, Criteria.new(:artist, value)
end
def self.album(value)
Expression.new :and, Criteria.new(:album, value)
end
def !()
Criteria.new @type, @value, !positive?
end
- def match(song)
+ def match?(song)
song.send(@type) == @value
end
end
class Expression
attr_accessor :type, :variables
def initialize(type, variables)
@type = type
@variables = variables
end
def &(other)
if other.type == @type and @type == :and
Expression.new :and, [@variables, other.variables].flatten
else
Expression.new :and, [self, other]
end
end
def |(other)
if other.type == @type and @type == :or
Expression.new :or, [@variables, other.variables].flatten
else
Expression.new :or, [self, other]
end
end
def !()
new_type = @type == :and ? :or : :and
Expression.new new_type, @variables.map { |variable| !variable }
end
- def match(thing)
- return @variables.match thing if @variables.respond_to?(:match)
+ def match?(thing)
+ return @variables.match? thing if @variables.respond_to?(:match?)
if @type == :and
- _match_all_variables thing
+ match_all_variables? thing
else
- _match_at_least_one_variable thing
+ match_at_least_one_variable? thing
end
end
- def _match_all_variables thing
- @variables.all? { |variable| variable.match thing }
+ private
+
+ def match_all_variables? thing
+ @variables.all? { |variable| variable.match? thing }
end
- def _match_at_least_one_variable thing
- @variables.any? { |variable| variable.match thing }
+ def match_at_least_one_variable? thing
+ @variables.any? { |variable| variable.match? thing }
end
end

Александър обнови решението на 31.10.2012 10:53 (преди над 11 години)

class Collection < Array
def self.parse(raw_data)
collection = Collection.new
raw_data.lines.map(&:chomp).each_slice(4) do |lines|
collection.push Song.new lines[0], lines[1], lines[2]
end
collection
end
def artists
map(&:artist).uniq
end
def names
map(&:name).uniq
end
def albums
map(&:album).uniq
end
def filter(expression)
Collection.new(select { |song| expression.match? song })
end
def adjoin(other)
result = Collection.new self
result.concat other
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
attr_accessor :type, :value
attr_writer :positive
def initialize(type, value, positive = true)
@type = type
@value = value
@positive = positive
end
def positive?
@positive
end
def self.name(value)
Expression.new :and, Criteria.new(:name, value)
end
def self.artist(value)
Expression.new :and, Criteria.new(:artist, value)
end
def self.album(value)
Expression.new :and, Criteria.new(:album, value)
end
def !()
Criteria.new @type, @value, !positive?
end
def match?(song)
song.send(@type) == @value
end
end
class Expression
attr_accessor :type, :variables
def initialize(type, variables)
@type = type
@variables = variables
end
def &(other)
if other.type == @type and @type == :and
Expression.new :and, [@variables, other.variables].flatten
else
Expression.new :and, [self, other]
end
end
def |(other)
if other.type == @type and @type == :or
Expression.new :or, [@variables, other.variables].flatten
else
Expression.new :or, [self, other]
end
end
def !()
new_type = @type == :and ? :or : :and
Expression.new new_type, @variables.map { |variable| !variable }
end
def match?(thing)
return @variables.match? thing if @variables.respond_to?(:match?)
if @type == :and
match_all_variables? thing
else
- match_at_least_one_variable? thing
+ match_any_variable? thing
end
end
private
def match_all_variables? thing
@variables.all? { |variable| variable.match? thing }
end
- def match_at_least_one_variable? thing
+ def match_any_variable? thing
@variables.any? { |variable| variable.match? thing }
end
end

Александър обнови решението на 31.10.2012 10:57 (преди над 11 години)

class Collection < Array
def self.parse(raw_data)
collection = Collection.new
raw_data.lines.map(&:chomp).each_slice(4) do |lines|
collection.push Song.new lines[0], lines[1], lines[2]
end
collection
end
def artists
map(&:artist).uniq
end
def names
map(&:name).uniq
end
def albums
map(&:album).uniq
end
def filter(expression)
Collection.new(select { |song| expression.match? song })
end
def adjoin(other)
result = Collection.new self
result.concat other
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
attr_accessor :type, :value
attr_writer :positive
def initialize(type, value, positive = true)
@type = type
@value = value
@positive = positive
end
def positive?
@positive
end
def self.name(value)
Expression.new :and, Criteria.new(:name, value)
end
def self.artist(value)
Expression.new :and, Criteria.new(:artist, value)
end
def self.album(value)
Expression.new :and, Criteria.new(:album, value)
end
def !()
Criteria.new @type, @value, !positive?
end
def match?(song)
song.send(@type) == @value
end
end
class Expression
attr_accessor :type, :variables
def initialize(type, variables)
@type = type
@variables = variables
end
def &(other)
if other.type == @type and @type == :and
Expression.new :and, [@variables, other.variables].flatten
else
Expression.new :and, [self, other]
end
end
def |(other)
if other.type == @type and @type == :or
Expression.new :or, [@variables, other.variables].flatten
else
Expression.new :or, [self, other]
end
end
def !()
new_type = @type == :and ? :or : :and
Expression.new new_type, @variables.map { |variable| !variable }
end
def match?(thing)
return @variables.match? thing if @variables.respond_to?(:match?)
if @type == :and
match_all_variables? thing
else
match_any_variable? thing
end
end
private
-
def match_all_variables? thing
@variables.all? { |variable| variable.match? thing }
end
def match_any_variable? thing
@variables.any? { |variable| variable.match? thing }
end
end