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

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

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

Резултати

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

Код

class Collection
include Enumerable
def self.parse(text)
songs = text.split("\n").each_slice(4)
.map do |name, artist, album, separator|
Song.new(name, artist, album)
end
Collection.new songs
end
def initialize(songs)
@songs = songs
end
def artists
@songs.map(&:artist).uniq
end
def albums
@songs.map(&:album).uniq
end
def names
@songs.map(&:name).uniq
end
def adjoin(other)
Collection.new to_a | other.to_a
end
def each
@songs.each { |song| yield song }
end
def filter(criteria)
criteria.filter self
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
def self.album(query)
QueryCriteria.new :album, query
end
def self.artist(query)
QueryCriteria.new :artist, query
end
def self.name(query)
QueryCriteria.new :name, query
end
def &(other)
ConjunctionCriteria.new self, other
end
def |(other)
DisjunctionCriteria.new self, other
end
def !
NegationCriteria.new self
end
def filter(collection)
Collection.new filter_to_array(collection)
end
end
class QueryCriteria < Criteria
def initialize(type, query)
@query, @type = query, type
end
def filter_to_array(collection)
collection.select { |song| song.send(@type) == @query }
end
end
class BinaryCriteria < Criteria
def initialize(left, right)
@left, @right = left, right
set_operator
end
def filter_to_array(collection)
@left.filter_to_array(collection).send(@operator,
@right.filter_to_array(collection))
end
end
class ConjunctionCriteria < BinaryCriteria
def set_operator
@operator = :&
end
end
class DisjunctionCriteria < BinaryCriteria
def set_operator
@operator = :|
end
end
class NegationCriteria < Criteria
def initialize(criteria)
@criteria = criteria
end
def filter_to_array(collection)
collection.to_a - @criteria.filter_to_array(collection)
end
end

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

...........

Finished in 0.01007 seconds
11 examples, 0 failures

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

Александър обнови решението на 25.10.2012 20:36 (преди около 12 години)

+class Collection
+ include Enumerable
+
+ def self.parse(text)
+ songs = []
+ text.split("\n").each_slice(4) do |name, artist, album, separator|
+ songs << Song.new(name, artist, album)
+ end
+ Collection.new songs
+ end
+
+ def initialize(songs)
+ @songs = songs
+ end
+
+ def artists
+ @songs.map(&:artist).uniq
+ end
+
+ def albums
+ @songs.map(&:album).uniq
+ end
+
+ def names
+ @songs.map(&:name).uniq
+ end
+
+ def adjoin(other)
+ Collection.new to_a | other.to_a
+ end
+
+ def each
+ @songs.each { |song| yield song }
+ end
+
+ def filter(criteria)
+ criteria.filter self
+ end
+
+end
+
+class Song
+
+ attr_accessor :name, :artist, :album
+ def initialize(name, artist, album)
+ @name, @artist, @album = name, artist, album
+ end
+end
+
+class Criteria
+
+ def self.album(query)
+ Criteria.new :album, query
+ end
+
+ def self.artist(query)
+ Criteria.new :artist, query
+ end
+
+ def self.name(query)
+ Criteria.new :name, query
+ end
+
+ def logic_factory(left_operand, right_operand, operator)
+ lambda do |collection|
+ left_operand.filter_as_array(collection).send(
+ operator,
+ right_operand.filter_as_array(collection))
+ end
+ end
+
+ def |(other)
+ new_criteria = Criteria.new
+ new_criteria.define_singleton_method(:filter_as_array,
+ logic_factory(self, other, '|'))
+ new_criteria
+ end
+
+ def &(other)
+ new_criteria = Criteria.new
+ new_criteria.define_singleton_method(:filter_as_array,
+ logic_factory(self, other, '&'))
+ new_criteria
+ end
+
+ def !
+ new_criteria = Criteria.new @type, @query
+ new_criteria.define_singleton_method(:filter_as_array, negate_filter!(self))
+ new_criteria
+ end
+
+ def negate_filter!(left_operand)
+ lambda do |collection|
+ collection.to_a - left_operand.filter_as_array(collection)
+ end
+ end
+
+
+ def initialize(type=nil, query=nil)
+ @query, @type = query, type
+ end
+
+ def filter_as_array(collection)
+ collection.select { |song| song.send(@type) == @query }
+ end
+
+ def filter(collection)
+ Collection.new filter_as_array(collection)
+ end
+
+
+end

Изискването за max 1 nesting level не е ли твърде свирепо в някои ситуации? Примерно трудно е да се използват дори неща като tap, а и доста код се повтаря, защото реално е невъзможно да дефинираш динамично метод без поне 2 nesting levels.

Александър обнови решението на 25.10.2012 21:56 (преди около 12 години)

class Collection
include Enumerable
def self.parse(text)
songs = []
text.split("\n").each_slice(4) do |name, artist, album, separator|
songs << Song.new(name, artist, album)
end
Collection.new songs
end
def initialize(songs)
@songs = songs
end
def artists
@songs.map(&:artist).uniq
end
def albums
@songs.map(&:album).uniq
end
def names
@songs.map(&:name).uniq
end
def adjoin(other)
Collection.new to_a | other.to_a
end
def each
@songs.each { |song| yield song }
end
def filter(criteria)
criteria.filter self
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
+
end
class Criteria
def self.album(query)
- Criteria.new :album, query
+ QueryCriteria.new :album, query
end
def self.artist(query)
- Criteria.new :artist, query
+ QueryCriteria.new :artist, query
end
def self.name(query)
- Criteria.new :name, query
+ QueryCriteria.new :name, query
end
- def logic_factory(left_operand, right_operand, operator)
- lambda do |collection|
- left_operand.filter_as_array(collection).send(
- operator,
- right_operand.filter_as_array(collection))
- end
+ def &(other)
+ ConjunctionCriteria.new self, other
end
def |(other)
- new_criteria = Criteria.new
- new_criteria.define_singleton_method(:filter_as_array,
- logic_factory(self, other, '|'))
- new_criteria
+ DisjunctionCriteria.new self, other
end
- def &(other)
- new_criteria = Criteria.new
- new_criteria.define_singleton_method(:filter_as_array,
- logic_factory(self, other, '&'))
- new_criteria
+ def !
+ NegationCriteria.new self
end
- def !
- new_criteria = Criteria.new @type, @query
- new_criteria.define_singleton_method(:filter_as_array, negate_filter!(self))
- new_criteria
+ def filter(collection)
+ Collection.new filter_to_array(collection)
end
- def negate_filter!(left_operand)
- lambda do |collection|
- collection.to_a - left_operand.filter_as_array(collection)
- end
+end
+
+class QueryCriteria < Criteria
+
+
+ def filter_to_array(collection)
+ collection.select { |song| song.send(@type) == @query }
end
def initialize(type=nil, query=nil)
@query, @type = query, type
end
- def filter_as_array(collection)
- collection.select { |song| song.send(@type) == @query }
+
+end
+
+class BinaryCriteria < Criteria
+
+ def filter_to_array(collection)
+ @left.filter_to_array(collection).send(@operator,
+ @right.filter_to_array(collection))
end
- def filter(collection)
- Collection.new filter_as_array(collection)
+end
+
+class ConjunctionCriteria < BinaryCriteria
+
+ def initialize(left, right)
+ @left, @right = left, right
+ @operator = :&
end
+end
-end
+class DisjunctionCriteria < BinaryCriteria
+
+ def initialize(left, right)
+ @left, @right = left, right
+ @operator = :|
+ end
+
+end
+
+class NegationCriteria < Criteria
+
+ def initialize(criteria)
+ @criteria = criteria
+ end
+
+ def filter_to_array(collection)
+ collection.to_a - @criteria.filter_to_array(collection)
+ end
+
+
+end

Александър обнови решението на 25.10.2012 21:59 (преди около 12 години)

class Collection
include Enumerable
def self.parse(text)
songs = []
text.split("\n").each_slice(4) do |name, artist, album, separator|
songs << Song.new(name, artist, album)
end
Collection.new songs
end
def initialize(songs)
@songs = songs
end
def artists
@songs.map(&:artist).uniq
end
def albums
@songs.map(&:album).uniq
end
def names
@songs.map(&:name).uniq
end
def adjoin(other)
Collection.new to_a | other.to_a
end
def each
@songs.each { |song| yield song }
end
def filter(criteria)
criteria.filter self
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
def self.album(query)
QueryCriteria.new :album, query
end
def self.artist(query)
QueryCriteria.new :artist, query
end
def self.name(query)
QueryCriteria.new :name, query
end
def &(other)
ConjunctionCriteria.new self, other
end
def |(other)
DisjunctionCriteria.new self, other
end
def !
NegationCriteria.new self
end
def filter(collection)
Collection.new filter_to_array(collection)
end
end
class QueryCriteria < Criteria
def filter_to_array(collection)
collection.select { |song| song.send(@type) == @query }
end
- def initialize(type=nil, query=nil)
+ def initialize(type, query)
@query, @type = query, type
end
end
class BinaryCriteria < Criteria
def filter_to_array(collection)
@left.filter_to_array(collection).send(@operator,
@right.filter_to_array(collection))
end
end
class ConjunctionCriteria < BinaryCriteria
def initialize(left, right)
@left, @right = left, right
@operator = :&
end
end
class DisjunctionCriteria < BinaryCriteria
def initialize(left, right)
@left, @right = left, right
@operator = :|
end
end
class NegationCriteria < Criteria
def initialize(criteria)
@criteria = criteria
end
def filter_to_array(collection)
collection.to_a - @criteria.filter_to_array(collection)
end
end

Александър обнови решението на 25.10.2012 22:23 (преди около 12 години)

class Collection
include Enumerable
def self.parse(text)
- songs = []
- text.split("\n").each_slice(4) do |name, artist, album, separator|
- songs << Song.new(name, artist, album)
- end
- Collection.new songs
+ Collection.new(text.split("\n")
+ .each_slice(4).map do |name, artist, album, separator|
+ Song.new(name, artist, album)
+ end)
end
def initialize(songs)
@songs = songs
end
def artists
@songs.map(&:artist).uniq
end
def albums
@songs.map(&:album).uniq
end
def names
@songs.map(&:name).uniq
end
def adjoin(other)
Collection.new to_a | other.to_a
end
def each
@songs.each { |song| yield song }
end
def filter(criteria)
criteria.filter self
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
def self.album(query)
QueryCriteria.new :album, query
end
def self.artist(query)
QueryCriteria.new :artist, query
end
def self.name(query)
QueryCriteria.new :name, query
end
def &(other)
ConjunctionCriteria.new self, other
end
def |(other)
DisjunctionCriteria.new self, other
end
def !
NegationCriteria.new self
end
def filter(collection)
Collection.new filter_to_array(collection)
end
end
class QueryCriteria < Criteria
def filter_to_array(collection)
collection.select { |song| song.send(@type) == @query }
end
def initialize(type, query)
@query, @type = query, type
end
end
class BinaryCriteria < Criteria
def filter_to_array(collection)
@left.filter_to_array(collection).send(@operator,
@right.filter_to_array(collection))
end
end
class ConjunctionCriteria < BinaryCriteria
def initialize(left, right)
@left, @right = left, right
@operator = :&
end
end
class DisjunctionCriteria < BinaryCriteria
def initialize(left, right)
@left, @right = left, right
@operator = :|
end
end
class NegationCriteria < Criteria
def initialize(criteria)
@criteria = criteria
end
def filter_to_array(collection)
collection.to_a - @criteria.filter_to_array(collection)
end
end

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

class Collection
include Enumerable
def self.parse(text)
- Collection.new(text.split("\n")
- .each_slice(4).map do |name, artist, album, separator|
+ songs = text.split("\n").each_slice(4)
+ .map do |name, artist, album, separator|
Song.new(name, artist, album)
- end)
+ end
+ Collection.new songs
end
def initialize(songs)
@songs = songs
end
def artists
@songs.map(&:artist).uniq
end
def albums
@songs.map(&:album).uniq
end
def names
@songs.map(&:name).uniq
end
def adjoin(other)
Collection.new to_a | other.to_a
end
def each
@songs.each { |song| yield song }
end
def filter(criteria)
criteria.filter self
end
end
class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
end
class Criteria
def self.album(query)
QueryCriteria.new :album, query
end
def self.artist(query)
QueryCriteria.new :artist, query
end
def self.name(query)
QueryCriteria.new :name, query
end
def &(other)
ConjunctionCriteria.new self, other
end
def |(other)
DisjunctionCriteria.new self, other
end
def !
NegationCriteria.new self
end
def filter(collection)
Collection.new filter_to_array(collection)
end
end
class QueryCriteria < Criteria
def filter_to_array(collection)
collection.select { |song| song.send(@type) == @query }
end
def initialize(type, query)
@query, @type = query, type
end
end
class BinaryCriteria < Criteria
def filter_to_array(collection)
@left.filter_to_array(collection).send(@operator,
@right.filter_to_array(collection))
end
end
class ConjunctionCriteria < BinaryCriteria
def initialize(left, right)
@left, @right = left, right
@operator = :&
end
end
class DisjunctionCriteria < BinaryCriteria
def initialize(left, right)
@left, @right = left, right
@operator = :|
end
end
class NegationCriteria < Criteria
def initialize(criteria)
@criteria = criteria
end
def filter_to_array(collection)
collection.to_a - @criteria.filter_to_array(collection)
end
end

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

class Collection
include Enumerable
def self.parse(text)
songs = text.split("\n").each_slice(4)
.map do |name, artist, album, separator|
Song.new(name, artist, album)
end
Collection.new songs
end
def initialize(songs)
@songs = songs
end
def artists
@songs.map(&:artist).uniq
end
def albums
@songs.map(&:album).uniq
end
def names
@songs.map(&:name).uniq
end
def adjoin(other)
Collection.new to_a | other.to_a
end
def each
@songs.each { |song| yield song }
end
def filter(criteria)
criteria.filter self
end
-
end
class Song
-
attr_accessor :name, :artist, :album
+
def initialize(name, artist, album)
@name, @artist, @album = name, artist, album
end
-
end
class Criteria
-
def self.album(query)
QueryCriteria.new :album, query
end
def self.artist(query)
QueryCriteria.new :artist, query
end
def self.name(query)
QueryCriteria.new :name, query
end
def &(other)
ConjunctionCriteria.new self, other
end
def |(other)
DisjunctionCriteria.new self, other
end
def !
NegationCriteria.new self
end
def filter(collection)
Collection.new filter_to_array(collection)
end
-
end
class QueryCriteria < Criteria
-
-
- def filter_to_array(collection)
- collection.select { |song| song.send(@type) == @query }
- end
-
-
def initialize(type, query)
@query, @type = query, type
end
-
+ def filter_to_array(collection)
+ collection.select { |song| song.send(@type) == @query }
+ end
end
class BinaryCriteria < Criteria
+ def initialize(left, right)
+ @left, @right = left, right
+ set_operator
+ end
def filter_to_array(collection)
@left.filter_to_array(collection).send(@operator,
@right.filter_to_array(collection))
end
-
end
class ConjunctionCriteria < BinaryCriteria
-
- def initialize(left, right)
- @left, @right = left, right
+ def set_operator
@operator = :&
end
-
end
class DisjunctionCriteria < BinaryCriteria
-
- def initialize(left, right)
- @left, @right = left, right
+ def set_operator
@operator = :|
end
-
end
class NegationCriteria < Criteria
-
def initialize(criteria)
@criteria = criteria
end
def filter_to_array(collection)
collection.to_a - @criteria.filter_to_array(collection)
end
-
-
+end
-end