Skip to content

Instantly share code, notes, and snippets.

@peterneorr
Created December 4, 2021 22:47
Show Gist options
  • Save peterneorr/cf2d118b932cbb5163bb96e42e6edb14 to your computer and use it in GitHub Desktop.
Save peterneorr/cf2d118b932cbb5163bb96e42e6edb14 to your computer and use it in GitHub Desktop.
Family Gift Exchange Program
//everybody to give/recieve a gift
List<string> players = new List<string> { "Peter", "Emma", "John", "Chris", "Patty", "Karen", "Jenny", "Sloane" };
players.Sort();
Dictionary<string,List<string>> restrictions = new Dictionary<string,List<string>>();
// Rule: players can't give to themselves
players.ForEach(p => restrictions.Add(p, new List<string> { p }));
// Rule: players can't give to their partner
restrictions["Peter"].Add("Emma");
restrictions["Emma"].Add("Peter");
restrictions["John"].Add("Chris");
restrictions["Chris"].Add("John");
restrictions["Jenny"].Add("Sloane");
// exchanges from last year
// tracked to ensure no repeat giving
var lastYear= new Dictionary<string, string>()
{
{"Emma", "John" },
{"Peter", "Karen" },
{"Karen", "Jenny" },
{"John", "Sloane" },
{"Chris", "Emma" },
{"Jenny", "Chris" },
{"Sloane", "Chris" },
{"Patty", "Peter" }
};
//using a seed that makes drawings repeatable
Random random = new Random(1);
Dictionary<string, string> draw(Dictionary<string, string> previous)
{
bool failed;
var result = new Dictionary<string, string>();
var chosen = new HashSet<string>();
do
{
failed = false;
foreach (var giver in players)
{
List<string> validChoices = new List<string>();
validChoices.AddRange(players.Where(p => !restrictions[giver].Contains(p) && previous[giver] != p && !chosen.Contains(p)));
if (validChoices.Count == 0)
{
failed = true;
result.Clear();
chosen.Clear();
break;
}
string recipient = validChoices.ElementAt(random.Next(validChoices.Count));
result[giver] = recipient;
chosen.Add(recipient);
}
}
while (failed);
return result;
}
int year = 2021;
var exchanges = new Dictionary<int, Dictionary<string, string>>();
while (year <= 2030)
{
exchanges.Add(year, lastYear);
lastYear = draw(lastYear);
year++;
}
Console.WriteLine($"YEAR,{string.Join(",", players.Select(p=>p.ToUpper()))}");
foreach (int y in exchanges.Keys.OrderBy(x=>x))
{
var map = exchanges[y];
string recipients = string.Join(",", players.Select(p => map[p]));
Console.WriteLine($"{y},{recipients}");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment