I am current attempting to do the magic squares program. However, I
dont have the magic in my squares. Could i get some assistance from
one of you experts.
I am
a) getting segmentation errors on this program
b) not sure if I have it coded correctly
#include<stdio.h>
#define ROW 32
#define COL 32
main (int argc,char** argv)
{
int size;
int magic_square[ROW][COL];
int column;
int n,r,c;
int first_element(int,int[][]);
void place_element(int[][],int,int);
size = (atoi(argv[1]));
while(size<=0 || (size %2) != 1 )
{
printf ("Please enter proper value\n");
scanf("%i",&size);
}
column=first_element(size,magic_square);
for (n=0;n<size*size-1;++n)
{
place_element(magic_square,column,size);
}
for(r=0;r<=(size-1);r++)
{
for(c=0;c<=(size-1);c++)
{
printf("%i\t",magic_square[r][c]);
}
}
}
#include<stdio.h>
#define ROW 32
#define COL 32
int first_element(int size,int magic_square[ROW][COL]){
int number_one=1;
int column;
int modified_column=(size-1) /2;
magic_square[0][modified_column]= number_one;
column=modified_column;
return column;
}
#include<stdio.h>
#define ROW 32
#define COL 32
void place_element(int magic_square[ROW][COL],int c,int size){
int place_e_c =c;
int r=0;
int place_e_r = 0;
int count;
r=r+2;
c=c+1;
if (r >= size) {r=r-size;}
if (c >= size) {c=c-size;}
if (magic_square[r][c]==0) {count++; magic_square[r][c]=count;}
else {r =place_e_r; c=place_e_c; r++;
if (r >= size){ r=r-size;}
count++;
magic_square[r][c]=count;
}} |
Hello Derekwtp,
I'll address the two general problems stated including some suggested
fixes:
#1 - Segmentation violation. I built this using gcc and using the
stack traceback in gdb, noted that you are passing a null pointer to
atoi if you don't have a command line parameter. Add something like
if (argc > 1)
to the line before that line to fix this problem.
General comment - always check your inputs. I also did a quick check
of the man page on my system for atoi. It recommends using strtol
instead of atoi, but for your use - atoi is probably OK. Note that
with my system - the man page also states you should
#include <stdlib.h>
prior to using atoi.
#2 - Getting the "right" answer. There are two parts to this. A quick
search using the phrase
magic square algorithm source code
led me to
http://remus.rutgers.edu/~rhoads/Code/magic.c
which is a comprehensive solver for magic squares. The algorithm it
looks like you are trying to use is labeled "lozenge method" in this
file and solves odd order magic squares. You could adapt this code to
solve the problem. [and be the end of the answer]
However, your code does have a number of problems. To help fix your
code [the second part of the answer] and avoid similar problems in
future programs, here are a few suggestions:
- Add
printf("\n");
to the print loop so you get a newline at the end of each row of
output.
When I make that change, the output for a 3 x 3 array is now...
0 1 0
0 20 0
0 0 13
or
0 1 0
0 8 0
0 0 1
which isn't close to the right answer. The answers vary if I enter
enter the array size on the command line or after the prompt. The
right answer according to magic is
8 3 4
1 5 9
6 7 2
The sum of each row and column is 15
- Change the declaration from
int count;
to
int count = 1;
(or whatever the "right" initial value is. Without the initializer,
you get a random junk value for count (as seen above in the two sample
outputs). With this change, the program consistently prints out
0 1 0
0 2 0
0 0 2
which still is not right, but at least consistent. I also expect this
should really be a static value - move it outside of place_element or
declare it static to fix that (otherwise, place_element "forgets" the
previous values of count). If this also applies to your other
variables - the same change is needed.
- I can't tell for sure if you are expecting "column" to change with
each call to place_element. In C, you need to pass an address to the
value if you want to modify it. That requires you to pass &column to
place_element and each reference to "c" changes to "*c". With that
change, the output is now
0 1 0
0 9 0
3 4 2
I provided these comments since to help you avoid the same mistakes in
new programs if you don't understand these concepts.
Beyond that - getting the "right answer" with your code will require
some further study of the differences between the calculations made in
magic and that done by your code. I will post this "answer" for now.
I you want to use something that works - fine, you have your answer
[use the algorithm in magic]. If you want to continue to pursue
fixing the existing code, post a "request for clarification" to the
answer to get more details.
--Maniac |
Request for Answer Clarification by
derekwtp-ga
on
03 Apr 2003 07:20 PST
I see what you saying and have altered the code to kind of reflect,
but I am still running into a display of:
[root@win186821wks nine]# ./nine 3
0 1 0
0 9 0
0 0 2
do you have any hints as to why this is the case?
#include<stdio.h>
#define ROW 32
#define COL 32
main (int argc,char** argv)
{
int size;
int magic_square[ROW][COL];
int* column;
int n,r,c;
int first_element(int,int[][]);
void place_element(int[][],int*,int);
size = (atoi(argv[1]));
while(size<=0 || (size %2) != 1 )
{
printf ("Please enter proper value\n");
scanf("%i",&size);
}
first_element(size,magic_square);
for(r=0;r<=(size-1);r++)
{
for(c=0;c<=(size-1);c++)
{
printf("%i\t",magic_square[r][c]);
}
printf ("\n");
}
}
#include<stdio.h>
#define ROW 32
#define COL 32
int first_element(int size,int magic_square[ROW][COL]){
int number_one=1;
int column;
int place_e_c;
int row=0;
int place_e_r;
int count=1;
int n;
int modified_column=(size-1) /2;
magic_square[0][modified_column]= number_one;
column=modified_column;
place_e_c =column;
place_e_r = 0;
row=row+2;
column=column+1;
for (n=0;n<size*size-1;++n){
if (row >= size) {row=row-size;}
if (column >= size) {column=column-size;}
if (magic_square[row][column]==0) {count++;
magic_square[row][column]=count;}
else {row =place_e_r; column=place_e_c; row++;
if (row >= size){ row=row-size;}
count++;
magic_square[row][column]=count;
}}}
|
Clarification of Answer by
maniac-ga
on
03 Apr 2003 16:41 PST
Hello Derekwtp,
Add something like
printf("MS[%d][%d] = %d\n", row, column, count);
after each time you assign a value to magic_square. When you now run
the program, you will see that you are assigning to the center
location several times (3, 4, 5, ...). That means that your method for
moving to the "next square" is incorrect.
Note that the code does not modify row and column after setting the
value in magic_square. This is where the problem likely is. I made
some changes to do the +2 / +1 to the row & column modulo the size -
that fixes it for a 3x3 magic square but not for 5x5. For a specific
fix, I will need to see the specific algorithm you are trying to
implement.
--Maniac
|
Request for Answer Clarification by
derekwtp-ga
on
05 Apr 2003 10:43 PST
I am almost done and I thank you for your help. But one last problem
baffles me. When I do a magic square of 3 it or 5 it works great:
[root@localhost nine]# ./nine 5
m_s[4][1],count = 6
m_s[3][0],count = 11
m_s[2][4],count = 16
m_s[1][3],count = 21
65
23 12 1 20 9
4 18 7 21 15
10 24 13 2 16
11 5 19 8 22
17 6 25 14 3
65
65 65 65 65 65
the count works awesome.
But when I do a magic square of 11 the count gets all messed up
1031267124
0 0 114 47 13 1 33 98 75
19 40
0 105 115 26 91 68 0 0 54
0 8
41 0 116 60 48 14 2 34 99
76 20
9 0 117 83 27 92 69 0 0
55 0
21 42 118 84 61 49 15 3 35
100 77
0 10 119 85 62 28 93 70 0
0 56
78 22 120 86 63 29 94 71 4
36 101
79 23 121 87 64 30 95 72 5
37 102
80 24 111 88 65 31 96 73 6
38 103
1049568659 58 112 89 66 32 97 74
18 39 -1073746728
104 81 113 90 67 4096 2736 53
1049568660 7 1031266520
1031267124
1049569071 1049569071 1049569071 1049569071
1049569071 1049569071 1049569071 1049569071
1049569071 1049569071 1049569071
code:
#include<stdio.h>
#define ROW 32
#define COL 32
main (int argc,char** argv)
{
int size;
int magic_square[ROW][COL];
int count;
int n,r,c;
int diag;
int row;
int column;
int column_add;
int first_element(int,int[][]);
void place_element(int[][],int*,int);
size = (atoi(argv[1]));
while(size<=0 || (size %2) != 1 )
{
printf ("Please enter proper value\n");
scanf("%d",&size);
}
first_element(size,magic_square);
/*add diags */
for (n=0;n<size;n++){
diag=diag + magic_square[n][n];
printf ("\t");
}
printf("%d\n\n",diag);
diag=0;
/*print square */
for(row=0;row<=(size-1);row++){
for(column=0;column<=(size-1);column++){
printf("%d\t",magic_square[row][column]);
}
printf("\n");
}
/*add diag*/
for (n=0;n<size;n++)
{
diag=diag + magic_square[n][n];
printf ("\t");
}
printf("%d\n\n",diag);
diag=0;
/*sum of columns */
for (count=0;count<size;count++){
column_add=column_add + magic_square[count][0];
}
for(count=0;count<size;count++){
printf ("%d\t",column_add);
}
column_add=0;
printf ("\n");
}
#include<stdio.h>
#define ROW 32
#define COL 32
int first_element(int size,int magic_square[ROW][COL]){
int number_one=1;
int column;
int place_e_c;
int row=0;
int place_e_r;
int count=1;
int n;
int modified_column=(size-1) /2;
magic_square[0][modified_column]= number_one;
column=modified_column;
for (n=0;n<size*size-1;++n){
place_e_c =column;
place_e_r = row;
row=row+2;
column=column+1;
if (row >= size) {row=row-size;}
if (column >= size) {column=column-size;}
if (magic_square[row][column]==0) {count++;
magic_square[row][column]=count;}
else {row =place_e_r; column=place_e_c; row++;
if (row >= size){ row=row-size;}
count++;
printf ("m_s[%d][%d],count = %d\n",row,column,count);
magic_square[row][column]=count;
}
}
}
|
Clarification of Answer by
maniac-ga
on
06 Apr 2003 07:33 PDT
Hello Derektwp,
Hmm. What you are providing certainly should work OK. I ran it on my
machine unmodified and it works correctly up to a size of 21 before it
shows the same kind of behavior. I made two changes:
- moved magic_square outside of main() to be a global declaration
[this makes it a static declaration]
- revised the declaration and definition of first_element to use
[ROW][COLUMN] for the sizes.
With these changes, the rest of the code worked OK up to size 31.
I also put some diagnostic code which basically did...
if (count % size != 1)
{
printf("Failed assertion\n");
for (r = 0; r<size; r++) {
for (c = 0; c<size; c++) {
printf("%5d", magic_square[r][c]);
}
printf("\n");
}
}
right after your current printf statement (ms[][],count). It shows the
array getting corrupted in a gradual manner after a few cycles. I am
not sure why - it *may* be a compiler bug since the code does look OK
otherwise. Hope this helps.
--Maniac
|