This answer focuses on Randomly Interleaving two lists with minimal bias.
It is important to use an appropriate algorithm and is a significant bias when using rnd.Next(2) == 0
when interleaving between two unequal-length lists. This bias is very obvious when interleaving a list of 2 elements and a list of 20 elements - the elements in the shorter list will be clustered near the front of the result. While such a bias is not always readily seen, it exists between any two unequal-length lists without taking the "weights" of the lists into account.
Thus, instead of using rnd.Next(2) == 0
to pick the source list, an unbiased implementation should pick fairly between all the remaining elements.
if (randInt(remaining(l1) + remaining(l2)) < remaining(l1)) {
// take from list 1
// (also implies list 1 has elements; as rand < 0 never matches)
} else {
// take from list 2
// (also implies list 2 has elements)
}
An implementation might look like this:
IEnumerable<T> RandomInterleave<T>(IEnumerable<T> a, IEnumerable<T> b) {
var rnd = new Random();
int aRem = a.Count();
int bRem = b.Count();
while (aRem > 0 || bRem > 0) {
var i = rnd.Next(aRem + bRem);
if (i < aRem) {
yield return a.First();
a = a.Skip(1);
aRem--;
} else {
yield return b.First();
b = b.Skip(1);
bRem--;
}
}
}
var list3 = RandomInterleave(list1, list2).ToList();