[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: [SOLUTION] Secret Santas (#2

Andre Nathan

10/3/2004 3:28:00 PM

Here goes mine... it has a method for sending mail which I haven't really
tested, so I left the call commented and printed the information instead.

Regards,
Andre

#!/usr/bin/env ruby
require 'net/smtp'

class Oops < Exception; end

def split_line(line)
name, surname, email = line.scan(/^(\w+)\s(\w+)\s+<(.+)>$/).flatten
return name, surname, email
end

def choose_person(name, surname, list)
person = list.find_all { |n, sn| sn != surname and n != name }.pop
raise Oops if person.nil?
list.delete(person)
return person
end

def split_list(list)
newlist = []
list.each { |line| newlist << split_line(line) }
return newlist
end

def send_mail(to, name, conf)
msg = <<__EOM__
From: Secret Santa Robot <#{conf[:from]}>
To: #{to}
Subject: Your chosen person

Your chosen person is #{name}.

Best regards,
The Secret Santa Robot
__EOM__

Net::SMTP.start(conf[:server], 25, conf[:domain], conf[:user],
conf[:password], conf[:auth].intern) do |smtp|
smtp.send_message msg, conf[:from], to
end
end

#
# Main
#
mailconf = {
:server => 'smtp.secretsanta.com',
:domain => 'secretsanta.com',
:from => 'robot@secretsanta.com',
:user => 'robot',
:password => 'tobor',
:auth => 'plain',
}

tries = 1
santas = split_list(ARGF.to_a)

families = {}
santas.each { |name, surname, email|
families[surname] = families[surname] ? families[surname] + 1 : 1
if families[surname] > santas.length / 2
raise "Too many people from the same family."
end
}

hash = {}
begin
people = santas.sort_by { rand }
santas.each { |name, surname, email|
pname, psname = choose_person(name, surname, people)
hash[email] = "#{pname} #{psname}"
}
rescue Oops
tries += 1
retry
end

#hash.each { |email, dest| send_mail(email, dest, mailconf) }
hash.each { |email, dest| puts "#{email} -> #{dest}" }
puts "Finished in #{tries} tries."