Reputation:
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.)
#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
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
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