James Gray
5/6/2005 12:52:00 AM
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
>