user16870582
user16870582

Reputation:

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;
}

Upvotes: 1

Views: 774

Answers (2)

lifezbeautiful
lifezbeautiful

Reputation: 1337

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;
}

Upvotes: 2

rturrado
rturrado

Reputation: 8054

For odd N or M you should print a line after the last iteration. You can't print a circle because the surface to print doesn't have 2 or more lines. One way to do it is checking if N or M are odd and, then, print a line to fill the spiral: https://godbolt.org/z/6oavKGPqf

I've added vert_line function and hor_line to your code to print that final line (vertical or horizontal).

void hor_line(int k){
    for (int i = 0+k; i < M-k; i++){
        arr[N-N+k][i] = nums;
        nums++;
    }
}

void vert_line(int k){
    for (int i = 0+k; i < N-k; i++){
        arr[i][M-1-k] = nums;
        nums++;
    }
}

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

Upvotes: 0

Related Questions