http://qs321.pair.com?node_id=9498
Category: Seasonal Oddities
Author/Contact Info Marburg (john.keating@may.ie)
Description:

Here is a little script that takes as input (STDIN) a :: field-delimited file of Names and associated Emails and emails everyone the name of the person they have to buy a present for. It is written in block format, just to make the perl students in my computer science department work a bit harder at figuring out how it works. There are no oddities, just plain Perl, and it should illustrate the way Perl can be used to solve problems.

The basic idea is that the script shouls choose someone from the list for each person in the list but not themselves of course (who wants to buy a pressie for themselves?). Each person should be emailed their chosen present recipient and no details of the selection should be maintained ... the program includes a copy of itself for educational purposes!

Anyway, could I have comments on improving the algorithm? Could I use a single Hash (appart from using a Hash of Lists)? Would it be better to shuffle a list and then select items one by one? Is there a better way than using grep to return the list of recipients? I have lots ot time to improve it before next Christmas.

Enjoy it, please! Marburg.

chomp,@_=split(/::/),($e{$_[0]},$l{$_[0]})=($_[1],0)while(<>);;
$m=qq#/usr/lib/sendmail#;$s=q#kris.kringle@north.pole#;;foreach
(keys%l){$l{$_}++;@L=grep{($l{$_}==0)}keys%l;;$x=int rand(@L);;
$l{$L[$x]}++;$l{$_}--;open(M,"|".$m." ".$e{$_});print M "From:"
," $s\n";print M "To: ", $e{$_},"\n";$t=qq/Your Kris Kringle /.
q/Recipient/;print M "Subject: $t!\n";print M "\n$t is: $L[$x].
\n\nK.K.";print M "\n\nPlease do NOT reply! 'I' am a program:",
"\n\n";open(T,$0);printf M while(<T>);close(T);close(M);}##JnK!