The little section that begins "if ($total == @santa...)" is there to prevent the following condition. Say we have three people, A, B. and C. A randomly gets assigned to B, then B gets assigned to A. At this point, the only person C can give a present to who has not gotten one is herself, which is not allowed! Hence, the little snippet above, which neatly solves that. Enjoy!#!perl use strict; my(@santa); my($total,$x,$y,$found,$old); my(%gift); my($name, $name2, $email, $email2); while(<>) { chomp; m/::/ && push(@santa, $_); } my $mail = "/usr/lib/sendmail -t -oi -odq"; my $mailfrom = "kris.kringle\@north.pole"; my $subject = "Your Kris Kringle Recipient"; ## Give everyone a present from a random person: $total=0; srand; for $y (@santa) { $found=0; $total++; while (!$found) { $x = $santa[rand @santa]; $y eq $x && next; ## No presents to self! ## What if the only person left is yourself? This solves that: if ($total == @santa && !$gift{$y}) { ## Switch with another! $old = $gift{$x}; $gift{$x}=$y; $gift{$y}=$old; last; } $gift{$x} && next; ## No more than one present per person $gift{$x}=$y; $found++; } } ## Now we send out the email: for $y (@santa) { ($name, $email) = split(/::/, $y); ($name2, $email2) = split(/::/, $gift{$y}); open(MAIL, "|$mail $email") || die "Could not open $mail: $!\n"; print MAIL <<"NORTHPOLE"; From: $mailfrom To: "$name" <$email> Subject: $subject $subject is: $name2 ($email2) K.K. Please do NOT reply! 'I' am a program: NORTHPOLE open(SELF, $0) || die "Could not open $0: $!\n"; while(<SELF>) { print MAIL; } close(SELF) || die "Could not close $0: $!\n"; close(MAIL) || die "Could not close $0: $!\n"; } exit;
In reply to RE: Kris Kringle Script
by turnstep
in thread Kris Kringle Script
by Marburg
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |