Google Answers Logo
View Question
 
Q: c programming assignment help ( Answered 4 out of 5 stars,   0 Comments )
Question  
Subject: c programming assignment help
Category: Computers > Programming
Asked by: derekwtp-ga
List Price: $6.00
Posted: 02 Apr 2003 18:41 PST
Expires: 02 May 2003 19:41 PDT
Question ID: 185199
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;
}}
Answer  
Subject: Re: c programming assignment help
Answered By: maniac-ga on 02 Apr 2003 20:18 PST
Rated:4 out of 5 stars
 
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
derekwtp-ga rated this answer:4 out of 5 stars
Thanks  Maniac

Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy