Magic square - odd output in a correct(?) program

Hi, I am doing the magic square problem for my c++ class and I am getting a few errors. I was hoping you guys could give me a few hints on:
Here's my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
  Magicsquare.cpp
  This program takes an odd number and uses it to form a magic square. A magic 
  square is a box which uses the odd number as its dimensions. it then finds the
  middle number in the top row and puts a 1 there. It then goes up diagonally 
  right one space. If it goes off the board on the top it goes to the bottom 
  of that column. If it goes off the board on the right then the row goes up by 
  1 and the column is set all the way to the left. If it goes both off right and 
  top then it moves the next number down one space. ex.(3) 8 1 6
                                                           3 5 7
                                                           4 9 2
*/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <cmath>
using namespace std;

void check(int& column, int& row, int rc);/*This function checks where the 
location of the point is, and whether it is off the board or not. It then puts 
them in the correct position.
preconditons: column, row, and rc have been given values.
postconditions: column and row have been corrected. */

const int MAX = 81;
int main()
{
   int array[MAX][MAX], rc, row, column, num(1), rcsqrd, rowcheck(0);
   char choice;
   
   cout << "Please enter your magic number(odd number used for dimensions of\n"
        << "rows and columns:";
   cin >> rc;
   rcsqrd = rc * rc;
   while(!(rc%2) && !(rc >= MAX) && !(rc <= 0))
   {
      cout << "Please enter an odd number less than or equal to " << MAX << ":\n"; 
      cin >> rc;    
   }
   column = (rc - 1) / 2;
   row = 0;
   for(int i = 0; i <= rcsqrd; i++)
   {
      if(array[column][row] != 0)
      {
         row++;
      }
      array[column][row] = num;
      check(column, row, rc);
      num++;
   }
   column = 0;
   row = 0;
   for(int i = 0; i <= rcsqrd; i++)
   {
      if(row == rc - 1)
      {
         cout << setw(3) << array[column][row] << endl;
         column = 0;
         row = rowcheck + 1;
         rowcheck++;
      }
      else
      {
         cout << setw(3) << array[column][row];
         row++;
      }
   }   
   system("pause");
   return 0;
}
void check(int& column, int& row, int rc)/*This function checks where the 
location of the point is, and whether it is off the board or not. It then puts 
them in the correct position.
preconditons: column, row, and rc have been given values.
postconditions: column and row have been corrected. */
{
   if(row - 1 < 0 && column + 1 > rc - 1)//case for diagonal
   {
      row++;
      return;
   }
   if(row - 1 < 0 && column + 1 <= rc - 1)//case for above 
   {
      column++;
      row = rc - 1;
      return;
   }
   if(column + 1 > rc - 1 && (row - 1 < rc - 1 && row - 1 >= 0))//case for side
   {
      row--;
      column = 0;
      return;
   }
   return;
}


However when I compile this with Dev c++ I get this:
say I enter 5, the output will be:
0 0 0 0 0
0 0 0 0
0 0 0
0 0
0
0 0 0 0 0 0 0 0 0 0

IE a upside down pyramid decrementing from the number entered and then a line that is double the number, all in 0's.

If anyone has any idea how to solve this problem with any hints Thank You in advance.
Last edited on
To get rid of the pyramid, you'll need to change this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   for(int i = 0; i <= rcsqrd; i++)
   {
      if(row == rc - 1)
      {
         cout << setw(3) << array[column][row] << endl;
         column = 0;
         row = rowcheck + 1;
         rowcheck++;
      }
      else
      {
         cout << setw(3) << array[column][row];
         row++;
      }
   }

This code does not display the contents of the magic square in the correct order. In order to create a grid of data in the console, you'll need to display only one row at a time, one cell at a time:
1
2
3
4
5
6
for (int y = 0; y < size; ++y) {  // This for loop goes through one row at a time.
    for (int x = 0; x < size; ++x) { // This for loop goes through one cell at a time for a given row.
        cout << setw(3) << array[x][y];
    }
    cout << endl;  // This is the end of the row.
}


Of course these should not be all zeros in the first place, so the magic square creation code is also incorrect.
Last edited on
Your method of creation is actually incorrect, which is probably the reason for the code not working properly.

Starting from the central column of the first row with the number 1, the fundamental movement for filling the squares is diagonally up and right, one step at a time. If a filled square is encountered, one moves vertically down one square instead, then continuing as before. When a move would leave the square, it is wrapped around to the last row or first column, respectively.

This will produce a 3x3 square.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	int array[3][3];
	int x = 1, y = 0;
	for ( int i = 0; i < 9; ++i) {
		array[x][y] = i + 1;

		// Move diagonally up-right
		++x; --y;

		// Wrap on out-of-bounds.
		if ( x > 2 ) x -= 3;
		if ( y < 0 ) y += 3;

		// If the cell is filled, backtrack.
		if ( array[x][y] != 0 ) {
			// Bakctrack, move diagonally down-left.
			--x; ++y;
			// Also move one cell down.
			++y;
		}

		// Wrap on out-of-bounds.
		if ( x < 0 ) x += 3;
		if ( y > 2 ) y -= 3;
	}
closed account (DLvRko23)
Here is the code magic square. :)))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
template <typename T> 
T** allocate_2d_matrix(int N1, int N2) 
{ 
    T** p = new T*[N1]; 
    for (int i=0; i<N2; i++) 
        p[i] = new T[N2]; 
    return (p); 
} 
 
template <typename T> 
void destroy_matrix(T** p, int N1, int N2) 
{ 
    for (int i=0; i<N2; i++) 
        delete [] p[i]; 
    delete [] p; 
} 
 

template <typename T> 
void fill(T** p, int N1, int N2) 
{ 
    for (int i=0; i<N1; i++) 
    for (int j=0; j<N2; j++) 
        p[i][j] = rand(); 
} 
 

template <typename T> 
T sum_row(T** p, int N1, int N2, int row) 
{ 
    assert(row < N1); 
    return (std::accumulate(p[row], p[row] + N2, 0)); 
} 

template <typename T> 
T sum_col(T** p, int N1, int N2, int col) 
{ 
    assert(col < N2);     

    int sum = 0; 
    for (int i=0; i<N1; i++) 
        sum += p[i][col]; 
    return (sum); 
} 

template <typename T> 
bool is_magic(T** p, int N1, int N2) 
{ 
    int sum_base = sum_row(p, N1, N2, 0);   
    for (int i=1; i<N1; i++) 
    { 
        if (sum_base != sum_row(p, N1, N2, i)) 
            return (false); 
    } 
   
    for (int i=1; i<N2; i++) 
    { 
        if (sum_base != sum_col(p, N1, N2, i)) 
            return (false); 
    } 
   
    int sum_diag1 = 0; 
    int sum_diag2 = 0; 
    for (int i=0; i<N1; i++) 
    for (int j=0; j<N2; j++) 
    { 
        sum_diag1 += p[i][j]; 
        sum_diag2 += p[i][N2-j-1]; 
    } 
 
    return  
        (sum_base == sum_diag1) && 
        (sum_base == sum_diag2); 
} 
 
void test_matrix() 
{ 
    const int N = 2; 
    int** p = allocate_2d_matrix<int>(N, N); 
    fill(p, N, N); 
     
    std::cout << is_magic(p, N, N) << std::endl; 
 
    destroy_matrix(p, N, N); 
}
Topic archived. No new replies allowed.