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 SubumissionThis 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
enddef to_s
return "#{@title} - #{@author} - #{@duration/1000} ms"
endattr_reader :author, :title, :duration
enddef 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
enddef getFirst(name)
return name[0, 1].capitalize
enddef getLast(name)
return name[-1, 1].capitalize
enddef duration(seq)
total=0
seq.each { |c| total+=c.duration }
return total
enddef 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
endmin_len = proc do |list|
min = list[0]
list.each do |i|
min=i if i.length<min.length
end
min
enddef 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
endsongs = 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
···
Begin forwarded message: