Skip to content

Instantly share code, notes, and snippets.

@lantoli
Last active August 29, 2015 14:07
Show Gist options
  • Save lantoli/8ad31c24b3f72279e43f to your computer and use it in GitHub Desktop.
Save lantoli/8ad31c24b3f72279e43f to your computer and use it in GitHub Desktop.
/*
We are asked to give a random derangement: http://en.wikipedia.org/wiki/Derangement
We use a slight modification of Fisher-Yates shuffle algorithm to make sure it's a derangement.
This algoritm works because all elements are moved one or more times to the left so at the end
all elements are in different positions than the original one.
But with this modification, random properties are not great. For example some permutations are more
likely than others, and there are some permutatations which can never happen.
An algorithm with better random properties (but slower) is:
http://epubs.siam.org/doi/pdf/10.1137/1.9781611972986.7
Also we're using Random, if we want stronger randomness we should use
crytographic random generation such as RNGCryptoServiceProvider.
*/
using System;
using System.Collections;
using System.Collections.Generic;
namespace Shuffle
{
public static class Shuffler {
public static List<T> Shuffle<T>(this List<T> list) {
var rnd = new Random();
var n = list.Count;
var copy = list.ToArray();
for (var i = n-1; i >= 1; i--) {
var j = rnd.Next(i);
var tmp = copy[i];
copy[i] = copy[j];
copy[j] = tmp;
}
return new List<T>(copy);
}
public static List<T> ShuffleOriginal<T>(this List<T> list) {
var rnd = new Random();
var copy = new List<T>(list);
var n = copy.Count;
for (var i = n-1; i >= 1; i--) {
var j = rnd.Next(i);
var tmp = copy[i];
copy[i] = copy[j];
copy[j] = tmp;
}
return copy;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment