Дамяна обнови решението на 31.10.2012 16:48 (преди около 12 години)
+class Song
+ attr_accessor :name, :artist, :album
+
+ def initialize(arr = [])
+ @name = arr[0] || ""
+ @artist = arr[1] || ""
+ @album = arr[2] || ""
+ end
+
+ def part_eq(other)
+ ((name == other.name and name != "") or
+ (artist == other.artist and artist != "") or
+ (album == other.album and album != ""))
+ end
+
+ def part_compare(other)
+ if not part_eq(other) then
+ return false
+ else
+ return true
+ end
+ end
+
+ def in_a(arr)
+ return true if arr == []
+ result = arr
+ res = result.map { |x| part_compare(x) }.take_while { |x| x == true}
+ arr.length == res.length
+ end
+
+ def eq_one_compare(other)
+ if other.is_a? Array then
+ return in_a(x)
+ else
+ return part_eq(x)
+ end
+ end
+
+ def eq_one(arr)
+ return true if arr == []
+ result = arr
+ res = result.map { |x| eq_one_compare(x) }.take_while { |x| x == false}
+ res == 1
+ end
+end
+
+class Collection
+ include Enumerable
+ attr_accessor :songs
+
+ def initialize(arr = [])
+ self.songs = arr
+ end
+
+ def each
+ i = 0
+ while i < songs.length
+ yield songs[i]
+ i += 1
+ end
+ end
+
+ def Collection.parse(text)
+ songs = []
+ text.each_line("\n\n") { |x| songs.push Song.new(x.split("\n")) }
+ Collection.new(songs)
+ end
+
+ def names
+ names = []
+ each { |x| names.push x.name }
+ names.uniq
+ end
+
+ def artists
+ artists = []
+ each { |x| artists.push x.artist }
+ artists.uniq
+ end
+
+ def albums
+ albums = []
+ each { |x| albums.push x.album }
+ albums.uniq
+ end
+
+ def filter (criteria)
+ result = select do |x|
+ x.in_a criteria.all and x.eq_one criteria.one and
+ (criteria.none == [] or (not x.in_a(criteria.none)))
+ end
+ Collection.new(result)
+ end
+
+ def adjoin(other)
+ new_songs = other.songs
+ songs.each do |x|
+ new_songs << x
+ end
+ Collection.new(new_songs)
+ end
+end
+
+class Criteria
+ attr_accessor :one, :all, :none
+ def initialize(all = [], one = [], none = [])
+ @one = one
+ @all = all
+ @none = none
+ end
+
+ def Criteria.name(name)
+ Criteria.new([Song.new([name])])
+ end
+
+ def Criteria.artist (artist)
+ Criteria.new([Song.new(["", artist])])
+ end
+
+ def Criteria.album (album)
+ Criteria.new([Song.new(["", "", album])])
+ end
+
+ def &(other)
+ other.all.each { |x| all << x }
+ other.none.each { |x| none << x }
+ Criteria.new(all, [], none)
+ end
+
+ def |(other)
+ other.all.each { |x| one << x }
+ one << all if all != []
+ Criteria.new([], one, [])
+ end
+
+ def !
+ all.each { |x| none << x }
+ Criteria.new([], [], none)
+ end
+end