eg. initial list = { 1, 2, 3, 4 }
2 sublists = [{ 1 }, { 2, 3, 4 }], [{ 1, 2 }, { 3, 4 }], [{ 1, 2, 3 }, { 4 }]
3 sublists = [{ 1 }, { 2 }, { 3, 4 }], [{ 1 }, { 2, 3 }, { 4 }], [{ 1, 2 }, { 3 }, { 4 }] etc
up to N sublists and all of them
I can come up with simple solution for N = 2 or 3 sublists but I need more of them. like 5 and would like to avoid bad code of generating each N separately
found a solution but its ugly as hell, just in case someone would like to solve this in the future
Code:
var initialList = new List<int>();
var X = 33;
int N = 5;
for (int i = 1; i < X; i++)
{
initialList.Add(i);
}
LinkedList<List<int>> sublists = new LinkedList<List<int>>();
if (N == 1)
{
sublists.AddLast(new List<int>(initialList));
//just one option
return;
}
for (int i = 0; i < N - 1; i++)
{
var newList = new List<int>();
newList.Add(initialList.ElementAt(i));
sublists.AddLast(newList);
}
var lastList = new List<int>();
sublists.AddLast(lastList);
lastList.AddRange(initialList.GetRange(N - 1, initialList.Count - N + 1));
var removingFrom = sublists.Last;
var removingFromList = removingFrom.Value;
var addingTo = removingFrom.Previous;
var addingToList = addingTo.Value;
var skipFirstCycle = false;
while (skipFirstCycle || removingFromList.Count > 1)
{
if (!skipFirstCycle)
{
do
{
//current step is now temporary stored in sublists variable
//need to be used here, or saved for later
var elem = removingFromList.First();
removingFromList.Remove(elem);
addingToList.Add(elem);
} while (removingFromList.Count > 1);
}
//current step is now temporary stored in sublists variable
//need to be used here, or saved for later
if (N == 2)
{
return;
}
//add first to previous
if (addingToList.Count > 1)
{
if (addingTo.Previous != null)
{
var firstElem = addingToList.First();
addingToList.Remove(firstElem);
addingTo.Previous.Value.Add(firstElem);
}
}
//leave second here
//merge rest and split
var mergedLeftovers = addingToList.GetRange(1, addingToList.Count - 1);
addingToList.RemoveRange(1, addingToList.Count - 1);
var level = removingFrom;
do
{
var first = level.Value.First();
mergedLeftovers.Add(first);
level.Value.Remove(first);
if (level.Next != null)
{
var leaveHere = mergedLeftovers.First();
mergedLeftovers.Remove(leaveHere);
level.Value.Add(leaveHere);
}
else
{
level.Value.AddRange(mergedLeftovers);
}
level = level.Next;
} while (level != null);
if (skipFirstCycle)
{
skipFirstCycle = false;
if (addingTo.Previous != null) {
removingFrom = sublists.Last;
removingFromList = removingFrom.Value;
addingTo = removingFrom.Previous;
addingToList = addingTo.Value;
}
}
if (removingFromList.Count == 1)
{
do
{
if (addingTo.Previous == null)
{
break;
}
skipFirstCycle = true;
removingFrom = removingFrom.Previous;
removingFromList = removingFrom.Value;
addingTo = addingTo.Previous;
addingToList = addingTo.Value;
} while (addingToList.Count == 1);
}
}






