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
>