Явор обнови решението на 27.10.2012 17:22 (преди над 12 години)
+class Song
+ attr_reader :name, :artist, :album
+
+ def initialize(song_name, song_artist, song_album)
+ @name = song_name
+ @artist = song_artist
+ @album = song_album
+ end
+end
+
+class Collection
+ attr_reader :songs
+
+ include Enumerable
+
+ def initialize(text)
+ @songs = []
+ text.each_line.map { |line| line.chomp }.
+ select { |line| line != "" }.each_slice(3).to_a.each do |line|
+ @songs << Song.new(line[0],line[1],line[2])
+ end
+ end
+
+ def Collection.parse(text)
+ Collection.new(text)
+ end
+
+ def each
+ songs.each { |song| yield song}
+ end
+
+ def names
+ @songs.map { |song| song.name }.uniq
+ end
+
+ def albums
+ @songs.map { |song| song.album }.uniq
+ end
+
+ def artists
+ @songs.map { |song| song.artist }.uniq
+ end
+
+ def filter(condition)
+ SubsetCollection.new(@songs.select { |song| condition.call(song) })
+ end
+
+ def adjoin(other)
+ SubsetCollection.new(@songs | other.songs)
+ end
+end
+
+class SubsetCollection < Collection
+ def initialize(init_songs)
+ @songs = init_songs
+ end
+end
+
+class Proc
+ def |(other)
+ Proc.new { |object| call(object) | other.call(object) }
+ end
+
+ def &(other)
+ Proc.new { |object| call(object) & other.call(object) }
+ end
+
+ def !()
+ Proc.new { |object| !call(object) }
+ end
+end
+
+class Criteria
+ def Criteria.name(text)
+ Proc.new { |song| song.name == text }
+ end
+
+ def Criteria.artist(text)
+ Proc.new { |song| song.artist == text }
+ end
+
+ def Criteria.album(text)
+ Prc.new { |song| song.album == text }
+ end
+end