# Secret Santa Challenge [duplicate]

Possible Duplicate:

Background: Secret Santa is a Western Christmas tradition in which members of a group or community are randomly assigned a person to whom they anonymously give a gift.

http://en.wikipedia.org/wiki/Secret_Santa

Ok, me and my work colleges did this today during our lunch hour - we made a secret algorithm santa pick random gifters and receivers.

Think of this question as a Christmas Programming Challenge to see who can come up with some of the most elegant solutions for this problem.

Input: The input should be an array ['Oliver', 'Paul', 'Rowan', 'Darren', 'Nick', 'Atif', 'Kevin']

Output A representation of something similar to key value pairs for the gifter and receiver. e.g.

Oliver -> Darren,
Paul -> Nick,
Rowan -> Kevin
Kevin -> Atif,
Darren -> Paul,
Nick -> Oliver,
Atif -> Rowan


Deadline: 15th December (for those late christmas shoppers)

Remember: you cannot have a person choosing themselves and the program must not spiral off into an infinite loop when gifter == receiver when there is only one person left.

Rules:

1. Must not have duplicates
2. Must be random (we all have different views on what is random - but you get my gist)
3. No Language constraints
4. Have fun

Here is mine (not golfed) in ruby:

require 'pp'

def move(array, from, to)
array.insert(to, array.delete_at(from))
end

gifters = ['Oliver', 'Paul', 'Rowan', 'Darren', 'Nick', 'Atif', 'Kevin'].shuffle!

move recievers, recievers.count - 1, 0



which spits out:

{"Nick"=>"Darren",
"Paul"=>"Nick",
"Kevin"=>"Paul",
"Rowan"=>"Kevin",
"Atif"=>"Rowan",
"Oliver"=>"Atif",
"Darren"=>"Oliver"}

• Input? Or do you want it hard-coded, as in your example? Does the resulting derangement have to be a single cycle, as implemented by your code, or can it be a product of disjoint cycles? – Peter Taylor Nov 26 '12 at 19:26
• I should have made it clearer in my post. The input should be an array ['Oliver', 'Paul', 'Rowan', 'Darren', 'Nick', 'Atif', 'Kevin'] and it can be a product of disjoint cycles - the rules are pretty open. – StudleyJr Nov 26 '12 at 19:29
• this is kinda trivial for a code challenge tag, and only one answer appears to be golf'd, so uh what's the objective here? – ardnew Nov 26 '12 at 21:03
• It's not quite exactly the same, the other one has a hardcoded list. – marinus Nov 26 '12 at 21:53
• the challenge is for fun - to produce the code in different languages with different approaches. The approach with the best intuitive wins (probably based on up votes, so the mass can decide) – StudleyJr Nov 26 '12 at 21:55

# k (29 20 chars)

{i!(1_i),*i:(-#x)?x}


{i!@[i:(-:#x)?x;,/|2 0N#!#x]}

Example

k){i!(1_i),*i:(-#x)?x}person1person2person3person4person5
person2| person1
person5| person3
person4| person2
person1| person5
person3| person4


Explanation - as above, shuffles list and maps to rotation of itself.

• very small - where can i get a copy of k to run this? – StudleyJr Nov 26 '12 at 20:19
• You can grab an evaluation version of the interpreter here kx.com/software.php . It's one interpreter for both q and k – skeevey Nov 26 '12 at 20:27
    NSMutableArray *people =
[NSMutableArray arrayWithArray:@[@"Oliver", @"Paul", @"Rowan", @"Darren", @"Nick", @"Atif", @"Kevin"]];
[people sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return (arc4random_uniform(3)-1);
}];

for (int i = 0;  i < [people count]; i++)
NSLog(@"%@ gifts %@", people[i], people[(i+1)%[people count]]);


## Ruby - 161 42 chars

#!/usr/bin/env ruby
require 'csv'



Usage

./secret_santa path_to_some_csv
=> {"Edward"=>"Alan", "Alan"=>"Charlie", "Charlie"=>"Dave", "Dave"=>"Brett", "Brett"=>"Edward"}


## Update

r=ARGV.shuffle!.dup;p ARGV.zip(r<<r.shift)

• As this is a code golf problem, I added the language and char count to your answer. I think there's still potential to shorten the code, for example using single char variable names or removing line breaks. – codeporn Nov 27 '12 at 9:34
• This can be shortened to 38 by replacing ARGV by $* r=$*.shuffle!.dup;p \$*.zip(r<<r.shift)` – Gazler Nov 21 '13 at 10:58