Орлин обнови решението на 30.10.2012 20:56 (преди около 12 години)
+class Track
+ attr_reader :name, :artist, :album
+
+ def initialize(track_data)
+ @name, @artist, @album = track_data.split("\n")
+ end
+
+ def to_s
+ "#{artist} - #{name}"
+ end
+end
+
+class Criteria
+ def self.album(track_album)
+ new Proc.new { |track| track.album == track_album }
+ end
+
+ def self.name(track_name)
+ new Proc.new { |track| track.name == track_name }
+ end
+
+ def self.artist(track_artist)
+ new Proc.new { |track| track.artist == track_artist }
+ end
+
+ def initialize(filter)
+ @filter = filter
+ end
+
+ def meet(track)
+ @filter.call(track)
+ end
+
+ def !
+ Criteria.new Proc.new { |track| !meet track }
+ end
+
+ def &(other)
+ Criteria.new Proc.new { |track| meet(track) & other.meet(track) }
+ end
+
+ def |(other)
+ Criteria.new Proc.new { |track| meet(track) | other.meet(track) }
+ end
+end
+
+
+class Collection < Array
+ def self.parse(data)
+ data.split("\n\n").each_with_object(Collection.new) do |track_info, tracks|
+ tracks << Track.new(track_info)
+ end
+ end
+
+ def filter(criteria)
+ Collection.new.adjoin select { |track| criteria.meet track }
+ end
+
+ def adjoin(collection)
+ collection.each { |track| self << track }
+ self
+ end
+end