Fill two dimensional array with spiral - c++

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

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

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

Related

How do I find errors in a recursive function?

I'm trying to find the smallest of the biggest sum of each column of every possible permutations of a given 2D array NxN, where the values in each row can shift towards the left. For example, the array
4 6
3 7
would have 4 possibles permutations:
4 6 6 4 4 6 6 4
3 7 3 7 7 3 7 3
The biggest sum of each permutation is respectively, 13, 11, 11, 13. Thus the smallest of the biggest sums is 11. I have written a recursive function that should work, but for some reason, it only works for arrays that are smaller than 6x6... I'm new at programming, and just recently learned about recursion, any help or counsel on how to think recursively and to debug code would be greatly appreciated...
For the array 4x4
7410 1371 2665 3195
4775 4130 6499 3414
300 2092 4009 7638
5351 210 7225 7207
The answer is 18349, and my code gives me the correct answer.
However, for the array 6x6
5219 842 7793 2098 5109 2621
1372 3253 3804 5652 810 1620
4894 6792 1784 4335 4772 6656
3203 1070 4716 5335 1157 6855
5529 2767 2205 408 7516 7454
375 7036 2597 5288 937 2893
The answer should be 23733, but I've got 24176. How is this possible?
Here's my code:
#include <iostream>
using namespace std;
#define MAX_N 1000
int n, matrix[MAX_N][MAX_N], shift[MAX_N] = {0}, minSum = 100000000;
void possibTree(int position){
//Base case
if(position == n){
for (int i = 0; i < n; i++) {
// Temporary array to store the values in the row that just shifted towards the left
int temp[MAX_N] = {0};
for (int j = 0; j < n; j++) {
if(j - shift[i] < 0)
temp[n+(j-shift[i])] = matrix[i][j];
else
temp[j-shift[i]] = matrix[i][j];
}
for (int k = 0; k < n; k++)
matrix[i][k] = temp[k];
}
int max = 0;
for (int i = 0; i < n; i++) {
int temp = 0;
for (int j = 0; j < n; j++) {
temp += matrix[j][i];
}
if(temp > max)
max = temp;
}
if(minSum > max)
minSum = max;
return;
}
for (int i = 0; i < n; i++) {
shift[position] = i;
possibTree(position+1);
}
return;
}
int main() {
while(cin >> n){
memset(matrix, 0, sizeof(matrix));
memset(shift, 0, sizeof(shift));
if(n == -1) // The user enters "-1" to end the loop and terminate the program.
return 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
possibTree(0);
cout << minSum << endl;
minSum = 100000000;
}
return 0;
}
Ok I believe I understand my mistake, I have to reset the matrix to its original state at the end of each base case, when the matrices are small, the code is still capable of finding all the possible biggest sums, but when the matrices got bigger, some of the possibilities weren't generated. Here's my code:
#include <iostream>
using namespace std;
#define MAX_N 1000
int n, matrix[MAX_N][MAX_N], OrigMatrix[MAX_N][MAX_N], shift[MAX_N] = {0}, minSum = 100000000;
void possibTree(int position){
//Base case
if(position == n){
for (int i = 0; i < n; i++) {
// Temporary array to store the values in the row that just shifted towards the left
int temp[MAX_N] = {0};
for (int j = 0; j < n; j++) {
if(j - shift[i] < 0)
temp[n+(j-shift[i])] = matrix[i][j];
else
temp[j-shift[i]] = matrix[i][j];
}
for (int k = 0; k < n; k++)
matrix[i][k] = temp[k];
}
int max = 0;
for (int i = 0; i < n; i++) {
int temp = 0;
for (int j = 0; j < n; j++) {
temp += matrix[j][i];
}
if(temp > max)
max = temp;
}
if(minSum > max)
minSum = max;
//EDITS
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = OrigMatrix[i][j];
}
}
return;
}
for (int i = 0; i < n; i++) {
shift[position] = i;
possibTree(position+1);
}
return;
}
int main() {
while(cin >> n){
memset(matrix, 0, sizeof(matrix));
memset(shift, 0, sizeof(shift));
if(n == -1) // The user enters "-1" to end the loop and terminate the program.
return 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
//EDITS
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
OrigMatrix[i][j] = matrix[i][j];
}
}
possibTree(0);
cout << minSum << endl;
minSum = 100000000;
}
return 0;
}

Merge operation of merge sort not working using c++ vectors

#include <iostream>
#include<vector>
std::vector<int> print(std::vector<int> answerVec){
for(int i = 0; i < answerVec.size(); i++){
std::cout<<answerVec.at(i)<<" ";
}
std::cout<<"\n";
return answerVec;
}
std::vector<int> Merge(std::vector<int> left, std::vector<int> right){
int leftSize = left.size();
int rightSize = right.size();
std::vector<int> finalVector;
int leftIterator = 0, rightIterator = 0;
while(leftIterator < leftSize && rightIterator < rightSize){
//std::cout<<"Left"<<left.at(leftIterator)<<"\n";
//std::cout<<"Right"<<right.at(rightIterator)<<"\n";
if((int)left.at(leftIterator) <= (int)right.at(leftIterator)){
finalVector.push_back(left.at(leftIterator));
leftIterator ++;
}
else{
finalVector.push_back(right.at(rightIterator));
rightIterator++;
}
//print(finalVector);
}
while(leftIterator < leftSize){
finalVector.push_back(left.at(leftIterator));
leftIterator ++;
//print(finalVector);
}
while(rightIterator < rightSize){
finalVector.push_back(right.at(rightIterator));
rightIterator++;
//print(finalVector);
}
return finalVector;
}
int main(){
std::vector<int> vecL,vecR,vec;
int n,input;
std::cin>>n;
for(int i = 0; i < n; i++){
std::cin>>input;
vecL.push_back(input);
}
for(int i = 0; i < n; i ++){
std::cin>>input;
vecR.push_back(input);
}
vec = Merge(vecL, vecR);
for(int i = 0; i < vec.size(); i++){
std::cout<<vec.at(i)<<" ";
}
return 0;
}
The Merge function above is not functioning properly when I am passing two sorted vectors as argument. Have tried for a while now but cannot make it work. Have commented some print statements that I was using for debugging. Any help would be much appreciated.
Thanks in advance
if((int)left.at(leftIterator) <= (int)right.at(leftIterator)){
Here, the second leftIterator should be rightIterator.

I want to delete a row from a matrix

I'm beginner in c++, and I want to make a program that delete a row from a matrix.. Like, If I say 3 3 2
1 2 3 it need to show 1 2 3
4 5 6 7 8 9
7 8 9
The program works like this: 3 = rows, 3 = columns, 2 = the deleted row. "3 3 2" is not a row...
I wrote this :
#include <iostream>
using namespace std;
int main() {
int N, M, v[100][100];
cin>>N>>M;
int i,j,p;
cin>>p;
for (i = 1; i <= N; ++i)
for (j = 1; j <= M; ++j)
cin>>v[i][j];
for (i = 1; i <= N; ++i) {
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<" ";
cout<<"\n";
}
for (i = p; i < N; ++i)
v[i][j]=v[i+1][j];
--N;
for (i = 1; i <= N; ++i){
for (j = 1; j <= N; ++j)
cout<<v[i][j]<<' ';
cout<<"\n";
}
return 0;
}
But it doesn't work.... Can someone help me?
modified code (it will work fine ):
#include <iostream>
using namespace std;
int main()
{
int N, M, v[100][100];
cin>>N>>M;
int i,j,p;
cin>>p;
for (i = 1; i <= N; ++i)
for (j = 1; j <= M; ++j)
cin>>v[i][j];
for (i = 1; i <= N; ++i)
{
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<" ";
cout<<"\n";
}
for (i = p; i < N; ++i)
for(j=1; j<=M; ++j)
v[i][j]=v[i+1][j];
--N;
for (i = 1; i <= N; ++i)
{
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<' ';
cout<<"\n";
}
return 0;
}
This doesn't work, what do you think j is doing in this code?
for (i = p; i < N; ++i)
v[i][j]=v[i+1][j];
--N;
You need to loop over rows and columns. Copy each column in every row greater that the row you want to delete. In other words you need nested loops here
for (i = p; i < N; ++i)
for (j = 1; j <= M; ++j)
v[i][j] = v[i+1][j];
--N;
You should use vector
#include <vector>
#include <iostream>
using namespace std;
int main()
{
//matrix
vector< vector<int> > V;
//To Add
for(int i=0; i<100; i++)
{
vector<int> R;
for(int j=0; j<100; j++)
{
int x;
cin>>x;
R.push_back(x);
}
V.push_back(R);
}
//To delete a row
int row_to_delete = 2;
V.erase(V.begin() + row_to_delete);
//To access
for(int i=0; i<V.size(); i++)
{
for(int j=0; j<V[i].size(); j++)
{
cout<<V[i][j];
}
}
}
vector<T> is class that use a template to create a dynamic array.
vector<int> is a var array int. V.push_back(T) you can add a element to array with type T, and with V.erase(V.begin() + int ) you can delete a element to array in this case a row. With V.size() you can take a elements count inside the array.

while loop does not work in C++ when I have return inside it

I'm new to C++ and working on the following code (which rotate a given 2d matrix), my code works fine for one rotation. Then I add a while loop to my code to make it more general, I noticed that the while code does not go to more iteration not mater what. I tried to bring the return MatrixRotateOutPut out of the while but then it was unknown. I also tried to add return 0 after while loop but it gives me another error.
I also checked these two links (Link1, Link2), but they werenot really helpful for me.
Thanks for the help in advance.
#include<iostream>
#include<vector>
using namespace std;
int MatrixPrint2D(vector<vector<int>> Input) {
for (int i = 0; i < Input.size(); i++) {
for (int j = 0; j < Input[0].size(); j++) {
printf("%d ", Input[i][j]);
}
printf("\n");
}
}
vector<vector<int>> MatrixRotate(vector<vector<int>> Input, int Irritation) {
while (Irritation > 0) {
cout << Irritation << "\n" << endl;
vector<vector<int>> MatrixRotateOutPut(Input[0].size(), vector<int>(Input.size(), 1));
for (int i = 0; i < Input.size(); i++) {
for (int j = 0; j < Input[0].size(); j++) {
MatrixRotateOutPut[j][Input.size() - 1 - i] = Input[i][j];
}
}
vector<vector<int>> Input(MatrixRotateOutPut.size(), vector<int>(MatrixRotateOutPut[0].size(), 1));
Input = MatrixRotateOutPut;
MatrixPrint2D(MatrixRotateOutPut);
printf("\n");
Irritation--;
return MatrixRotateOutPut;
}
}
int main() {
//Define a matrix for testing:
vector<vector<int>> Matrix2(4, vector<int>(5, 1));
int R = 2;
int C = 4;
vector<vector<int>> MatrixInput(R, vector<int>(C, 1));;
for (int i = 0; i < MatrixInput.size(); i++) {
for (int j = 0; j < MatrixInput[0].size(); j++) {
int temp;
temp = i ^ (2 * j);
MatrixInput[i][j] = temp;
}
}
cout << "MatrixInput:" << endl;
MatrixPrint2D(MatrixInput);
printf("\n");
vector<vector<int>> OutPut2 = MatrixRotate(MatrixInput, 4);
return 0;
}
Edit: I am sorry for this question.
You may do the following:
Move the return outside of the loop
Move the declaration of the returned variable outside of the loop.
So:
vector<vector<int>> MatrixRotate(vector<vector<int>> Input, int Irritation) {
vector<vector<int>> MatrixRotateOutPut;
while (Irritation > 0) {
cout << Irritation << "\n" << endl;
MatrixRotateOutPut = vector<vector<int>>(Input[0].size(), vector<int>(Input.size(), 1));
for (int i = 0; i < Input.size(); i++) {
for (int j = 0; j < Input[0].size(); j++) {
MatrixRotateOutPut[j][Input.size() - 1 - i] = Input[i][j];
}
}
vector<vector<int>> Input(MatrixRotateOutPut.size(), vector<int>(MatrixRotateOutPut[0].size(), 1));
Input = MatrixRotateOutPut;
MatrixPrint2D(MatrixRotateOutPut);
printf("\n");
Irritation--;
}
return MatrixRotateOutPut;
}

C++ - my for loop is not starting

I wrote this code for java first. It should print the 2D array as a spiral. I wanted to try it in c++.. in java; there was a draw method. But c++ is not accepting array as a return type (can done by pointers) so I deleted the draw method and copied inside the main method. I commented the draw method where starts and ends. But now; the for loop which is after the draw method (i commented it too) is not starting. What's the problem; I cannot see it... Thanx for help.
int T ;
scanf("%d", &T);
int num[T];
for(int i = 0; i < T; i++){
scanf("%d", &num[i]);
}
for(int m = 0; m < T; m++){
int n = num[m];
int a[n][n];
//draw -start
int all = n*n;
int x = 0, y=0;
for(int counter=1; counter<=all; counter++){
for(int i = 0; i < n; i++){
a[x][y] = counter++;
y++;}
x++; y--;
for(int i = 0; i < n-1; i++){
a[x][y] = counter++;
x++;}
x--; y--;
for(int i = 0; i < n-1; i++){
a[x][y] = counter++;}
x--; y++;
for(int i = 0; i < n-2; i++){
a[x][y] = counter++;}
y++; x++; n = n-2;}
//draw - end
//this for is not starting
for(int i = 0; i<n; i++){
printf("a");
for(int j = 0; i<n; j++){
printf("a");
printf("%d ", a[i][j]);
}
printf("\n");
}
You decrement n in the biggest cycle.
n = n-2;
This is why n < 0 when you reach the for you speak of and it is not looping.
I am almost certain you did not meant to modify n in this loop.
I neatened up your code and provided my answer in the comments.
int T ;
scanf("%d", &T);
int num[T];
for(int i = 0; i < T; i++){
scanf("%d", &num[i]);
}
for(int m = 0; m < T; m++){
int n = num[m];
int a[n][n];
//draw -start
int all = n*n;
int x = 0, y=0;
for(counter=1; counter<=all; counter++){
for(int i = 0; i < n; i++) {
a[x][y] = counter++;
y++;
}
x++;
y--;
for(int i = 0; i < n-1; i++) {
a[x][y] = counter++;
x++;
}
x--;
y--;
for(int i = 0; i < n-1; i++) {
a[x][y] = counter++;
}
x--;
y++;
for(int i = 0; i < n-2; i++) {
a[x][y] = counter++;
}
y++;
x++;
n = n-2; //n = n - 2; all = n * n times?
}
for(int i = 0; i<n; i++){
printf("a");
for(int j = 0; i<n; j++){
printf("a");
printf("%d ", a[i][j]);
}
printf("\n");
}
}
in particular look at this line
n = n-2; //n = n - 2; all = n * n times?