Begin forwarded message: > From: Pedro <pedro.wotan / mundo-r.com> > Date: May 5, 2005 7:48:36 PM CDT > To: submission / rubyquiz.com > Subject: [SOLUTION] Please Forward: Ruby Quiz Subumission > > > This is my very first Ruby script, and I supose it could be > terrific, but I enjoyed it very much :). > > Bye > class Song > def initialize(author, title, duration) > @author=author > @title=title > @duration=duration > end > > def to_s > return "#{@title} - #{@author} - #{@duration/1000} ms" > end > > attr_reader :author, :title, :duration > end > > def parse(name) > list = Hash.new > artist = Regexp.new('<Artist name=\"([^>]+)\">') > song = Regexp.new('<Song name=\"([^>]+)\" id=\'(\d+)\' duration= > \'(\d+)\'/>') > a, t, d = '', '', 0 > i=0 > File.open(name) do |file| > file.each_line do |line| > i+=1 > if ar=artist.match(line) > a = ar[1] > elsif ar=song.match(line) > t = ar[1] > d = ar[3].to_i > key = getFirst(t) > list[key] = Array.new unless list[key] > list[key] << Song.new(a, t, d) > end > end > end > return list > end > > def getFirst(name) > return name[0, 1].capitalize > end > > def getLast(name) > return name[-1, 1].capitalize > end > > def duration(seq) > total=0 > seq.each { |c| total+=c.duration } > return total > end > > def search(songs, first, last) > posibles = Array.new > if songs.key?(getLast(first.title)) > if(songs[getLast(first.title)].find {|c| > c.title==last.title}) > return [last] > end > sig = songs.delete(getLast(first.title)) > for i in sig > if v=search(songs, i, last) > posibles << (v << i) > end > end > # what do you choose? > unless posibles.empty? > return yield(posibles) if block_given? > return posibles[0] > end > end > return nil > end > > ## SELECTION METHODS > min_dur = proc do |list| > min = list[0] > list.each do |i| > min=i if duration(i)<duration(min) > end > min > end > > min_len = proc do |list| > min = list[0] > list.each do |i| > min=i if i.length<min.length > end > min > end > > def exact_len(dur) > return proc do |list| > min = list[0] > list.each do |i| > min=i if (duration(i)-dur).abs<(duration(min)- > dur).abs > end > min > end > end > > songs = parse('SongLibrary.xml') > > ## PREDEFINED LIST > #title1, title2 = '21st Century Army', 'Deconstruction' > #v1, v2 = songs[getFirst(title1)], songs[getFirst(title2)] > #first = v1.find {|c| c.title == title1} > #last = v2.find {|c| c.title == title2} > > ## RANDOM LIST > v1 = songs[songs.keys[rand(songs.length)]] > v2 = songs[songs.keys[rand(songs.length)]] > first, last = v1[rand(v1.length)], v2[rand(v2.length)] > > puts first.to_s + ' ===> ' + last.to_s > > result=search(songs, first, last, &min_len) > > if result > result.push(first) > puts result.reverse > else > puts 'There is no way!' > end >