# 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"}
``````
-

## marked as duplicate by dmckeeNov 26 '12 at 21:19

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. – Oliver Atkinson 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) – Oliver Atkinson 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}`person1`person2`person3`person4`person5
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? – Oliver Atkinson 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 – slackwear 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. – air_blob 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