From: Robo Date: 2004-10-03T21:24:56+09:00 Subject: [SOLUTION] Secret Santas (#2) --------------060500060701010903090801 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit I'm still new to Ruby, but giving this a crack anyway. I could have made more classes to model the problem better, but didn't bother. Everything's done by a Hat with higher intelligence than regular hats (that doesn't deserve a capital H). To run, type "ruby santa.rb", then enter each person's name and email in the format specified. When you're done the script tells you the result of the selection. The email part is a bit rogue, but that's just a matter of creating a more comprehensive email message. It's disabled by default, just uncomment the lines in Hat#notify. It doesn't take into account of creating loops smaller than total number of people. i.e. If there're 4 people, 3 of them maybe Secret Santas of each other, leaving one stranded. Robo --------------060500060701010903090801 Content-Type: text/plain; name="santa.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="santa.rb" require 'net/smtp' #a very smart Hat that even knows how to email class Hat #represents a member of the Christmas gathering Member = Struct.new(:firstName, :lastName, :email, :minion) def initialize @members = [] @pool = [] end #put a new member into the hat def put(firstName, lastName, email) member = Member.new(firstName, lastName, email) @members << member @pool << member end #match each Secret Santa to a person def match @members.each do |santa| santa.minion = draw(santa) notify(santa) end end #draw a person out of the hat for a Secret Santa def draw(santa) validPool = filter(santa) person = validPool.at(rand(validPool.size)) @pool.delete(person) end #filter out people who're in the same family as Secret Santa def filter(santa) @pool.select do |member| member.lastName != santa.lastName end end #notify each Secret Santa who they'll be watching over def notify(santa) if santa.minion != nil msg = "#{santa.firstName} #{santa.lastName} is watching over " + "#{santa.minion.firstName} #{santa.minion.lastName}" else msg = "#{santa.firstName} #{santa.lastName} is watching over nobody" end puts msg #Net::SMTP.start('smtp.example.com', 25) do |smtp| # smtp.send_message(msg, 'hat@magic.com', santa.email) #end end end def main h = Hat.new while (s = gets()) != nil s.scan(/^(.*?) (.*?) <(.*?)>$/) do |firstName, lastName, email| h.put(firstName, lastName, email) end end h.match end if __FILE__ == $0 main end --------------060500060701010903090801--