Search code examples
c#listsortingswapreorderlist

Sort or reorder list alternately in C#


I have a list of numbers 1 and 0 only with fixed size of 25.

Example:

List<int>() { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

And I need to reorder or sort the list to:

Pattern A:

List<int>() { 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };

or

Pattern B:

List<int>() { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 };

Max no of "1" in the list will always less than 13. The list will loop and search for nearest "1" and replace with current index if current index is "0" (either start from left or right only).

Here are my code snippets to produce both patterns above:

List SlotMapLP1 = new List() { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

int i = 0, j = 0, k = 0, waferCount = 0, loopCtr = 0;
for (i = 0; i < SlotMapLP1.Count; i++ )
{
    if (SlotMapLP1[i] == 1)
        waferCount++;
}

List<int> ptnOne = new List<int>(SlotMapLP1);
List<int> ptnTwo = new List<int>(SlotMapLP1);

j = ptnOne.Count - 1;
while (j >= 0 && loopCtr <= waferCount) //list will start to traverse from right to left
{
    if ((ptnOne[j] == 0 && (j + 1) % 2 > 0))
    {
        k = j - 1;
        while (k >= 0)
        {
            if (ptnOne[k] == 1 && (ptnOne[k] != ptnOne[j]))
            {
                ExtensionMethods.Swap(ptnOne, k, j); //swap the two items
                loopCtr++;
                break;
            }
            k--;
        }
    }
    else
    {
        if (j == 0 || j + 1 == ptnOne.Count) break;
        if (ptnOne[j - 1] == 0 && ptnOne[j + 1] == 1)
        {
            k = j - 1;
            while (k >= 0)
            {
                if (ptnOne[k] == 0 && (ptnOne[k] != ptnOne[j]))
                {
                    ExtensionMethods.Swap(ptnOne, j, k); //swap the two items
                    loopCtr++;
                    break;
                }
                k--;
            }
        }
        else
        {
            k = j - 1;
            while (k >= 0)
            {
                if (ptnOne[k] == 1 && (ptnOne[k] != ptnOne[j]))
                {
                    ExtensionMethods.Swap(ptnOne, j, k); //swap the two items
                    loopCtr++;
                    break;
                }
                k--;
            }
        }
    }
    j--;
}

loopCtr = 0; j = 0; k = 0;
while (j < ptnTwo.Count && loopCtr <= waferCount)//list will start to traverse from left to right
{
    if (ptnTwo[j] == 0 && (j + 1) % 2 > 0)
    {
        k = j + 1;
        while (k < ptnTwo.Count)
        {
            if (ptnTwo[k] == 1 && (ptnTwo[k] != ptnTwo[j]))
            {
                ExtensionMethods.Swap(ptnTwo, j, k); //swap the two items
                loopCtr++;
                break;
            }
            k++;
        }
    }
    else
    {
        if (j == 0 || j + 1 == ptnOne.Count) break;
        if (ptnTwo[j + 1] == 0 && ptnTwo[j - 1] == 1)
        {
            k = j + 1;
            while (k < ptnTwo.Count)
            {
                if (ptnTwo[k] == 0 && (ptnTwo[k] != ptnTwo[j]))
                {
                    ExtensionMethods.Swap(ptnTwo, j, k); //swap the two items
                    loopCtr++;
                    break;
                }
                k++;
            }
        }
        else
        {
            k = j + 1;
            while (k < ptnTwo.Count)
            {
                if (ptnTwo[k] == 1 && (ptnTwo[k] != ptnTwo[j]))
                {
                    ExtensionMethods.Swap(ptnTwo, j, k); //swap the two items
                    loopCtr++;
                    break;
                }
                k++;
            }
        }
    }
    j++;
}

However, I do face some problem. Not all list input can be sorted or reorder to alternately if I use this method.

Are there better way or method to perform this type of sorting?


Solution

  • There's a solution that doesn't involve swapping elements in the list. You only have to figure out the pattern.

    If there is only one 1:

    1000000000000000000000000

    There's a "1" followed by 24 zeros.

    If there are 2 ones:

    1010000000000000000000000

    There's a "101" pattern followed by 22 zeros.

    See where I'm getting at?

    For 3 ones:

    1010100000000000000000000

    There's a "10101" pattern followed by 20 zeros.

    So you only have to count the number of ones and build your pattern from there. The algorithm then becomes:

    1. Let n = number of ones in the list
    2. If there are no ones, both patterns A and B is just 25 zeros.
    3. Else build alternating pattern of length n * 2 - 1.
    4. For pattern A, concatenate 25 - (n * 2 - 1) zeros and the alternating pattern.
    5. For pattern B, concatenate the alternating pattern and 25 - (n * 2 - 1) zeros. (Or the reverse of pattern A)