Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

A Constructive Approach to Multi-Pole Ball Sorting

Tech 4

Consider a system with only two colors. To consolidate all balls of the first color onto the first peg, let k represent the quantity of the first color currently on the first peg. Shift the top k elements from the second peg to the third (auxiliary) peg. Sequentially move elements from the first peg: elements matching the first color go to the second peg, while others go to the third peg. Relocate the k elements from the second peg to the first, followed by the remaining elements from the third peg to the first. At this stage, the first peg is perfectly partitioned (non-target on top, target on bottom). Move the non-target elements from the first peg to the third. Finally, distribute the elements from the second peg—target color to the first peg, remainign to the third.

cpp int match_cnt = 0; for (int v : pegs[1]) if (v == 1) match_cnt++; for (int i = 0; i < match_cnt; i++) transfer(2, 3); while (heights[1] > 0) { if (pegs[1].back() == 1) transfer(1, 2); else transfer(1, 3); } for (int i = 0; i < match_cnt; i++) transfer(2, 1); for (int i = 0; i < cap - match_cnt; i++) transfer(3, 1); while (heights[3] > 0) transfer(3, 2); while (heights[1] > 0 && pegs[1].back() == 2) transfer(1, 3); while (heights[2] > 0) { if (pegs[2].back() == 1) transfer(2, 1); else transfer(2, 3); }

Expand the logic to handle n colors by iteratively isolating one color at a time. Designate the target color as 1 and all others as 0. The objective is to gather all 1s into a specific column. This requires two specialized columns: one entirely composed of 0s and one that is complete empty. By logically swapping column indices, we can assign the n-th column as the uniform 0 column and the (n+1)-th as the empty column.

To bring all target elements of a column i to the top, let k be the count of target elements in column i. Move k elements from the uniform column to the empty column. Distribute elements from column i: target elements to the uniform column, non-target to the empty column. Swap column i with the empty column, then swap column i with the uniform column. This operation effectively filters the target elements to the top of column i.

After establishing the uniform and empty columns, apply the elevation procedure to columns x through n-1. Once all target elements in these columns are at the top, move them to the empty column. Swap the empty column with column x. The remaining space in columns x+1 through n can then be filled with the leftover non-target elements from column x.

cpp void isolateColor(int col, int target) { establishUniformColumn(col, target); for (int i = col; i <= num_cols - 1; i++) { int match_cnt = 0; for (int v : pegs[i]) if (v == target) match_cnt++; for (int j = 0; j < match_cnt; j++) transfer(num_cols, num_cols + 1); while (heights[i] > 0) { if (pegs[i].back() == target) transfer(i, num_cols); else transfer(i, num_cols + 1); } swap_logical(i, num_cols + 1); swap_logical(i, num_cols); } for (int i = col; i <= num_cols - 1; i++) { while (heights[i] > 0 && pegs[i].back() == target) transfer(i, num_cols + 1); } swap_logical(num_cols + 1, col); swap_logical(num_cols, num_cols + 1); for (int i = col + 1; i <= num_cols; i++) { while (heights[i] < cap) transfer(num_cols + 1, i); } }

Assume we are building the uniform 0 column on column x. Let k be the number of target elements in column x. Move k elements from the n-th column to the (n+1)-th column. Distribute elements from column x: target to the n-th column, non-target to the (n+1)-th. Move the non-target elements from the (n+1)-th column back to column x. Process column x+1: move non-target elements to column x until it is full, directing any overflow or target elements to the (n+1)-th column. Finally, swap column x with the n-th column, and column x+1 with the (n+1)-th column.

cpp void establishUniformColumn(int col, int target) { int match_cnt = 0; for (int v : pegs[col]) if (v == target) match_cnt++; for (int i = 0; i < match_cnt; i++) transfer(num_cols, num_cols + 1); while (heights[col] > 0) { if (pegs[col].back() == target) transfer(col, num_cols); else transfer(col, num_cols + 1); } for (int i = 0; i < cap - match_cnt; i++) transfer(num_cols + 1, col); while (heights[col + 1] > 0) { if (pegs[col + 1].back() == target || heights[col] == cap) transfer(col + 1, num_cols + 1); else trasnfer(col + 1, col); } swap_logical(col, num_cols); swap_logical(col + 1, num_cols + 1); }

Repeat the consolidation for the first n-2 colors. The remaining two columns are resolved using the base case logic.

cpp #include #include #include

using namespace std;

const int MAX_COLS = 55; const int MAX_CAP = 405;

vector pegs[MAX_COLS]; int heights[MAX_COLS]; int peg_id[MAX_COLS]; int num_cols, cap; vector<pair<int, int>> moves;

void transfer(int src, int dest) { pegs[dest].push_back(pegs[src].back()); pegs[src].pop_back(); heights[dest]++; heights[src]--; moves.push_back({peg_id[src], peg_id[dest]}); }

void swap_logical(int a, int b) { swap(pegs[a], pegs[b]); swap(heights[a], heights[b]); swap(peg_id[a], peg_id[b]); }

void establishUniformColumn(int col, int target) { int match_cnt = 0; for (int v : pegs[col]) if (v == target) match_cnt++; for (int i = 0; i < match_cnt; i++) transfer(num_cols, num_cols + 1); while (heights[col] > 0) { if (pegs[col].back() == target) transfer(col, num_cols); else transfer(col, num_cols + 1); } for (int i = 0; i < cap - match_cnt; i++) transfer(num_cols + 1, col); while (heights[col + 1] > 0) { if (pegs[col + 1].back() == target || heights[col] == cap) transfer(col + 1, num_cols + 1); else transfer(col + 1, col); } swap_logical(col, num_cols); swap_logical(col + 1, num_cols + 1); }

void isolateColor(int col, int target) { establishUniformColumn(col, target); for (int i = col; i <= num_cols - 1; i++) { int match_cnt = 0; for (int v : pegs[i]) if (v == target) match_cnt++; for (int j = 0; j < match_cnt; j++) transfer(num_cols, num_cols + 1); while (heights[i] > 0) { if (pegs[i].back() == target) transfer(i, num_cols); else transfer(i, num_cols + 1); } swap_logical(i, num_cols + 1); swap_logical(i, num_cols); } for (int i = col; i <= num_cols - 1; i++) { while (heights[i] > 0 && pegs[i].back() == target) transfer(i, num_cols + 1); } swap_logical(num_cols + 1, col); swap_logical(num_cols, num_cols + 1); for (int i = col + 1; i <= num_cols; i++) { while (heights[i] < cap) transfer(num_cols + 1, i); } }

int main() { if (!(cin >> num_cols >> cap)) return 0; for (int i = 1; i <= num_cols; i++) { pegs[i].resize(cap); for (int j = 0; j < cap; j++) cin >> pegs[i][j]; heights[i] = cap; peg_id[i] = i; } peg_id[num_cols + 1] = num_cols + 1;

if (num_cols == 2) {
    int match_cnt = 0;
    for (int v : pegs[1]) if (v == 1) match_cnt++;
    for (int i = 0; i < match_cnt; i++) transfer(2, 3);
    while (heights[1] > 0) {
        if (pegs[1].back() == 1) transfer(1, 2);
        else transfer(1, 3);
    }
    for (int i = 0; i < match_cnt; i++) transfer(2, 1);
    for (int i = 0; i < cap - match_cnt; i++) transfer(3, 1);
    while (heights[3] > 0) transfer(3, 2);
    while (heights[1] > 0 && pegs[1].back() == 2) transfer(1, 3);
    while (heights[2] > 0) {
        if (pegs[2].back() == 1) transfer(2, 1);
        else transfer(2, 3);
    }
} else {
    for (int i = 1; i < num_cols - 1; i++) isolateColor(i, i);
    int match_cnt = 0;
    for (int v : pegs[num_cols - 1]) if (v == num_cols - 1) match_cnt++;
    for (int i = 0; i < match_cnt; i++) transfer(num_cols, num_cols + 1);
    while (heights[num_cols - 1] > 0) {
        if (pegs[num_cols - 1].back() == num_cols - 1) transfer(num_cols - 1, num_cols);
        else transfer(num_cols - 1, num_cols + 1);
    }
    for (int i = 0; i < match_cnt; i++) transfer(num_cols, num_cols - 1);
    for (int i = 0; i < cap - match_cnt; i++) transfer(num_cols + 1, num_cols - 1);
    while (heights[num_cols + 1] > 0) transfer(num_cols + 1, num_cols);
    while (heights[num_cols - 1] > 0 && pegs[num_cols - 1].back() == num_cols) transfer(num_cols - 1, num_cols + 1);
    while (heights[num_cols] > 0) {
        if (pegs[num_cols].back() == num_cols - 1) transfer(num_cols, num_cols - 1);
        else transfer(num_cols, num_cols + 1);
    }
}
cout << moves.size() << "\n";
for (auto [src, dest] : moves) cout << src << " " << dest << "\n";
return 0;

}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.