c++arraysspiral

Fill two dimensional array with spiral


The task is to fill two dimens array [N][M] in a spiral with numbers starting with 1.

My code doesn't work when one of the elements (N or M) is odd or both are odd. When I use two different even or two same even numbers it works.

I need help to do it so it would work in any case, with any N and M.

p.s. please keep my code (don't make dynamic array, keep defines and etc.)

https://pastebin.com/9HufHYBg

#include <iostream>

#define N 6
#define M 4

int nums = 1; 
int p = 1;

int arr[N][M];

using namespace std;

void printArr(){
    for (int i = 0; i < N; i++){
        for (int j = 0; j < M; j++){
            cout << arr[i][j] << "\t";
        }
        cout << endl;
    }
}

void circle (int k){    
    
    // levo pravo
    for (int i = 0+k; i < M-k; i++){
        arr[N-N+k][i] = nums;
        nums++;
    }
    // verh niz
    nums--;
    for (int i = 0+k; i < N-k; i++){
        arr[i][M-1-k] = nums;
        nums++;
    }
    // pravo levo
    nums--;
    for (int i = M-p; i >= 0+k; i--){
        arr[N-1-k][i] = nums;
        nums++;
    }
    // niz verh
    nums--;
    for (int i = N-p; i > 0+k; i--){
        arr[i][0+k] = nums;
        nums++;
    }
    p++;
}


int main(){
    
    if (M<N){   
        for (int k = 0; k < M/2; k++){      
            circle(k);  
        }   
    } else {
        for (int k = 0; k < N/2; k++){      
            circle(k);  
        }
    }
    
    printArr();
    
    return 0;
}

Solution

  • To summarise, I managed to solve using two changes: first, we change the limits of the main call so that we reach the centre everytime, and second, we avoid overwriting of already populated indices. Here, I stop this overwriting by checking by using an if statement before every assignment. But, cleaner solutions might be possible for the same.

    Tested for various combinations (odd-odd, even-even, odd-even, odd-odd-not-same, odd-odd-same etc..)

    #include <iostream>
    
    #define N 9
    #define M 7
    
    int nums = 1; 
    int p = 1;
    
    int arr[N][M];
    
    using namespace std;
    
    void printArr(){
        for (int i = 0; i < N; i++){
            for (int j = 0; j < M; j++){
                cout << arr[i][j] << "\t";
            }
            cout << endl;
        }
    }
    
    void circle (int k){    
        
        // levo pravo
        for (int i = 0+k; i < M-k; i++){
            if (arr[N-N+k][i] == 0)
                arr[N-N+k][i] = nums;
            nums++;
        }
        // verh niz
        nums--;
        for (int i = 0+k; i < N-k; i++){
            if (arr[i][M-1-k] == 0)
                arr[i][M-1-k] = nums;
            nums++;
        }
        // pravo levo
        nums--;
        for (int i = M-p; i >= 0+k; i--){
            if (arr[N-1-k][i]==0)
                arr[N-1-k][i] = nums;
            nums++;
        }
        // niz verh
        nums--;
        for (int i = N-p; i > 0+k; i--){
            if (arr[i][0+k] == 0)
                arr[i][0+k] = nums;
            nums++;
        }
        p++;
    }
    
    
    int main(){
        
        if (M<N){   
            for (int k = 0; k < (M+1)/2; k++){      
                circle(k);  
            }   
        } else {
            for (int k = 0; k < (N+1)/2; k++){      
                circle(k);  
            }
        }
        
        printArr();
        
        return 0;
    }