Search code examples
c#permutation

Permutations of List by Swapping 2 Values


I have a list which contains information on a Part:

List<Part> partList = new List<Part>
{
    new Part
    {
        Length = 150,
        Width = 100
    },
    new Part
    {
        Length = 300,
        Width = 50,
    },
    new Part
    {
        Length = 100,
        Width = 50,
    },
};

And what I want from this is permutations which get all combinations of Length x Width for each Part.

Example:

List<Part> x = new List<Part>
{
    new Part
    {
        Length = 100,
        Width = 150
    },
    new Part
    {
        Length = 300,
        Width = 50,
    },
    new Part
    {
        Length = 100,
        Width = 50,
    },
};

List<Part> n = new List<Part>
{
    new Part
    {
        Length = 150,
        Width = 100
    },
    new Part
    {
        Length = 50,
        Width = 300,
    },
    new Part
    {
        Length = 100,
        Width = 50,
    },
};

And it essentially swaps all the lengths and widths within each Part and gets all the combinations for this.


Solution

  • Here's my solution. I know it can be simplified a lot, but it works for what I need. Feel free to post any modifications.

    public List<List<Part>> RotatePartList(List<Part> partList, List<List<Part>> rotatedList, int initialCounter = 0, int position = 0, int secondCounter = 1)
            {
                List<Part> tempPartList = new List<Part>();
                foreach (var part in partList)
                {
                    tempPartList.Add(new Part
                    {
                        Label = part.Label,
                        Length = part.Length,
                        Width = part.Width
                    });
                }
    
                // Swap only one of each number (i.e. The first number is swapped, then the second, then the third etc.)
                if (initialCounter <= partList.Count() - 1)
                {
                    tempPartList[initialCounter].Length = partList[initialCounter].Width;
                    tempPartList[initialCounter].Width = partList[initialCounter].Length;
                    rotatedList.Add(tempPartList);
                    RotatePartList(partList, rotatedList, initialCounter + 1);
                }
    
                // Only run this if there are more than 2 parts
                if (partList.Count() > 2)
                {
                    // Swap each item and everything ahead of it one at a time (i.e swap the first item and second, then first and third, then first and fourth etc.)
                    if (position != partList.Count() - 1)
                    {
                        if (secondCounter <= partList.Count() - 1)
                        {
                            tempPartList[position].Length = partList[position].Width;
                            tempPartList[position].Width = partList[position].Length;
    
                            tempPartList[secondCounter].Length = partList[secondCounter].Width;
                            tempPartList[secondCounter].Width = partList[secondCounter].Length;
    
                            rotatedList.Add(tempPartList);
    
                            RotatePartList(partList, rotatedList, initialCounter, position, secondCounter + 1);
                        }
                        else
                        {   // The current item and all the ones ahead have been swapped one at a time, so go to next item
                            position += 1;
                            secondCounter = position + 1;
                            RotatePartList(partList, rotatedList, initialCounter, position, secondCounter);
                        }
                    }
                }
    
                // If all values have been swapped, add the original list and the one where ALL items are swapped
                rotatedList.Add(partList);
    
                if (partList.Count() > 1)
                { 
                    for (var i = 0; i <= partList.Count() - 1; i++)
                    {
                        tempPartList[i].Length = partList[i].Width;
                        tempPartList[i].Width = partList[i].Length;
                    }
                    rotatedList.Add(tempPartList);
                }
    
                return rotatedList;
            } 
    

    My solution is to swap one Part at a time, then swap the Part at index 1 and every Part ahead of it one at a time (i.e. index 1 and 2, then 1 and 3, then 1 and 4 etc.) Before moving onto index 2 and doing the same forward rotation.