Решение на Втора задача от Ангел Лазаров

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

Към профила на Ангел Лазаров

Резултати

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

Код

class Song
attr_reader :name
attr_reader :artist
attr_reader :genre, :subgenre
attr_reader :tags
def initialize(name, artist, genre, subgenre=nil, tags=[])
@name = name
@artist = artist
@genre = genre
@subgenre = subgenre
@tags = tags
end
def tags
all_tags = @tags | [genre.downcase]
all_tags |= [subgenre.downcase] if subgenre != nil
all_tags
end
end
class Collection
def initialize(songs_as_string, artist_tags)
@songs = parse_all_songs(songs_as_string, artist_tags)
end
def find(criteria)
@songs.select {|song| meets_criteria? song, criteria}
end
private
def parse_single_song(song_as_string, artist_tags)
attributes = song_as_string.split('.')
name = attributes[0].strip
artist = attributes[1].strip
genre = attributes[2].split(',')[0].strip
subgenre = attributes[2].split(',').fetch(1,'').strip
subgenre = nil if subgenre == ''
tags = attributes.fetch(3, '').split(',').map{|attr| attr.strip}
additional_tags = artist_tags.fetch(artist, [])
Song.new(name, artist, genre, subgenre, tags|additional_tags)
end
def parse_all_songs(songs_as_string, artist_tags)
songs = []
songs_as_string.lines {|s| songs.push(parse_single_song(s, artist_tags))}
songs
end
def meets_criteria?(song, criteria)
has_tags = [criteria.fetch(:tags,[])].flatten.all? do |tag|
if tag.end_with?('!')
!song.tags.include? tag.chop
else
song.tags.include? tag
end
end
same_name = song.name == criteria.fetch(:name, song.name)
same_artist = song.artist == criteria.fetch(:artist, song.artist)
meets_filter = criteria.fetch(:filter, ->(s){true}).(song)
[has_tags, same_name, same_artist, meets_filter].all?
end
end

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

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

Finished in 0.55399 seconds
12 examples, 0 failures

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

Ангел обнови решението на 30.10.2011 22:11 (преди над 12 години)

+class Song
+ attr_reader :name
+ attr_reader :artist
+ attr_reader :genre, :subgenre
+ attr_reader :tags
+
+ def initialize(name, artist, genre, subgenre=nil, tags=[])
+ @name = name
+ @artist = artist
+ @genre = genre
+ @subgenre = subgenre
+ @tags = tags
+ end
+
+ def tags
+ all_tags = @tags | [genre.downcase]
+ all_tags |= [subgenre.downcase] if subgenre != nil
+ all_tags
+ end
+end
+
+class Collection
+ def initialize(songs_as_string, artist_tags)
+ @songs = parse_all_songs(songs_as_string, artist_tags)
+ end
+
+ def find(criteria)
+ @songs.select {|song| meets_criteria? song, criteria}
+ end
+
+ private
+
+ def parse_single_song(song_as_string, artist_tags)
+ attributes = song_as_string.split('.')
+ name = attributes[0].strip
+ artist = attributes[1].strip
+ genre = attributes[2].split(',')[0].strip
+ subgenre = attributes[2].split(',').fetch(1,'').strip
+ subgenre = nil if subgenre == ''
+ tags = attributes.fetch(3, '').split(',').map{|attr| attr.strip}
+ additional_tags = artist_tags.fetch(artist, [])
+ Song.new(name, artist, genre, subgenre, tags|additional_tags)
+ end
+
+ def parse_all_songs(songs_as_string, artist_tags)
+ songs = []
+ songs_as_string.lines {|s| songs.push(parse_single_song(s, artist_tags))}
+ songs
+ end
+
+ def meets_criteria?(song, criteria)
+ has_tags = [criteria.fetch(:tags,[])].flatten.all? do |tag|
+ if tag.end_with?('!')
+ !song.tags.include? tag.chop
+ else
+ song.tags.include? tag
+ end
+ end
+ same_name = song.name == criteria.fetch(:name, song.name)
+ same_artist = song.artist == criteria.fetch(:artist, song.artist)
+ meets_filter = criteria.fetch(:filter, ->(s){true}).(song)
+ [has_tags, same_name, same_artist, meets_filter].all?
+ end
+end