I'v been watching your thread but I was waiting until I got your program working myself before responding.
I think your approach is flawed as follows:
You loop through k = 0 to N*N-1 OK, but your effort to somehow assign values to the a[i][j] by iterating over i and j directly (as in the 2 for loops) and applying the rules along the way seems like the wrong way.
According to:
Let k be an integer that has the values from 1 to n^2.
Place one (1) in the last column, middle row. |
We start with row = N/2; (not (N+1)/2, check it. N=7 expect midRow = 3 and 7/2 = 3)
and col = N-1
1st assignment then is to:
a[N/2][N-1] = 1;
Of course that's actually
a[row][col] = k;
but row = N/2, col = N-1 and k = 1 right now.
From this point on you must let the rules be your guide in assigning values for row and col for the next assignment (of k+1).
There will be no for loops over i or j, just the for loop over k.
Here's what I have starting off:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
unsigned N = 3;
unsigned** pSq = new unsigned int*[N];
for( unsigned i = 0; i < N; ++i )
pSq[i] = new unsigned int[N]();
unsigned row = N/2;// current row
unsigned col = N - 1;// current col
unsigned int k = 1;// value for: pSq[row][col] = k;
while( k <= N*N )// one element will be assigned each iteration
{
// new k to be used
pSq[row][col] = k;
// find k, row, col for next loop
++k;
if( k > N*N ) break;
// apply rules to find next values for row and col
}
|
The "usual" rule for the next value of row is row+1, and for col it is col+1
** exceptions **
rule #1: if move would be to below square
col += 1; row = 0; instead of row+=1, col+=1 (typ)
rule #2: if move would be to right of square
row+= 1; col = 0;
rule #3 i move would be to below and right of square (ie from [N-1][N-1])
col -= 1; row = row; (ie no change). This is a move to the left.
The key (I found) was that the rule about moving left if an element has already been assigned applies to ALL moves, so after figuring new row and col values based on the other rules, you must apply "move left if occupied" until an unassigned space is found.
I wrote a moveLeft() function. You give it the values for row, col which the rules would give, it keeps going left until it finds a space where a = 0 still.
The instructions seemed unclear regarding the move left:
if a move takes you to a cell that is already occupied..., then k +1 should be placed immediately to the left of k. |
What if col = 0? Wrap to col=N-1? What about row? If col changes, does row decrease? If row=0, col=0 do we move to N-1, N-1? Turns out, yes to all.
This is what "move left" means.
I hope that is enough of a hint. Post back if you have problems or questions with this approach.
Using this algorithm I was able to get the following for N=3,5,7:
for N = 3
4 3 8
9 5 1
2 7 6
row sums = 15 15 15
col sums = 15 15 15
diag sums = 15 15
for N = 5
11 10 4 23 17
18 12 6 5 24
25 19 13 7 1
2 21 20 14 8
9 3 22 16 15
row sums = 65 65 65 65 65
col sums = 65 65 65 65 65
diag sums = 65 65
for N = 7
22 21 13 5 46 38 30
31 23 15 14 6 47 39
40 32 24 16 8 7 48
49 41 33 25 17 9 1
2 43 42 34 26 18 10
11 3 44 36 35 27 19
20 12 4 45 37 29 28
row sums = 175 175 175 175 175 175 175
col sums = 175 175 175 175 175 175 175
diag sums = 175 175
|