Magic Square 2D array - c

I am tasked with creating a C program that will read a .txt file, convert it into a 2D array, and test whether or not it is a magic square (meaning that all columns, rows, and diagonals add up to [n(n^2 + 1)] / 2), where n is the number of integers in the row, column, or diagonal. The txt file contains 3 4x4 squares, 3 sets of 16 and the last number is zero. So the magic sum is 34. I have gotten the rows to add up, but I can't seem to figure out the columns or the diagonals. Also, I feel that with the way my code is going right now, it will only read the file once, and cannot read the other two 4x4 sets. Here is my code (sorry, it's pretty sloppy right now. I've been wrestling with this for a while, so it got a little messy)
int main (){
int array1[4][4], array2[4][4], array3[4][4], number=1, row, col, diag;//I messed with adding new arrays to send to functions, but it doesn't really do anything
FILE *file1;
file1 = fopen ("testdata.txt", "r");
if(file1!=NULL){
printf(" Square Perfect?\n----------------------------\n");
row=testRows(file1, array1, number);
col=testCols(file1, array3, number);
number++;
}
else
printf("File could not be read.\n");
return 0;
}
int testRows (FILE *file1, int array1[4][4], int number){
int i, j=0, r=0, q, tru=9000, array2[4][4], input;
if (file1!=NULL){
for(q=0; q<4; q++){
j=0;
r=0;
for (i=0; i<4; i++){
fscanf(file1, "%d", &array1[i][j]);
r=r+array1[i][j];//sum of rows
}
j++;
if (r!=34){
tru=0;
break;
}
if (r==34){
tru=1;
}
}
}
return tru;
}
int testCols(FILE *file1, int array1[4][4], int num){ //this is the problematic function
int i, j=0, r=0, q, tru=9000, array2[4][4], input;
if(num==1){//ignore this
file1 = fopen("testdata.txt", "r");//Before I added this, this function would read the next 16 numbers in the file and read their rows, when I need them to read the first 16 and their columns. I feel like this will really hurt when I need the function to read further into the file. Any suggestions?
}
if (file1!=NULL){
for(j=0; j<4; j++){ r=0;
for(i=0; i<4; i++){
fscanf(file1, "%d", &array1[i][j]);
printf("%d ", array1[i][j]);
r+=array1[i][j];// sum
printf(" ~%d~ ", r); //this is so I can see what the sum currently is. For some reason, it will only add up rows and not columns.
}
printf("\n");
}
//^^^^^ I have moved i's and j's around all over the place, but no matter what, it will print and add the sum of each row.
}
// return tru; variable tru is to return to main whether or not the square is magic; have not gotten that far yet.
}
/*int testDiag(){
}
*/
Thank you, any help would be greatly appreciated
Here is testdata.txt:
1 15 14 4 10 11 8 5 7 6 9 12 16 2 3 13
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 3 4 5 6 7 12 8 9 15 7 9 4 3 12 13
0
UPDATE!
I redid the entire program, works perfectly now. Take a look:
int main(){
int i, j, q, row, col, diag, array1[4][4], magic, magic1, magic2, w, sqn=1;
FILE *file1;
file1= fopen("testdata.txt", "r");
printf(" Square Magic?\n --------------------------------------\n");
for(w=0; w<3; w++){
if(file1!=NULL){
for(i=0; i<4; i++){
for(j=0; j<4; j++){
fscanf(file1, "%d", &array1[i][j]);
}}
}
for(i=0; i<4; i++){
row=0;
for(j=0; j<4; j++){
row+=array1[i][j];
}
if(row==34){
magic=1;
}
if(row!=34){
magic=0;
break;
}
}
for(i=0; i<4; i++){
col=0;
for(j=0; j<4; j++){
col+=array1[j][i];
}
if(col==34){
magic1=1;
}
if(col!=34){
magic1=0;
break;
}
}
for(i=0; i<4; i++){
diag=0;
for(j=0; j<4; j++){
diag+=array1[j][i];
}
if(diag==34){
magic2=1;
}
if(diag!=34){
magic2=0;
break;
}
}
printf(" Square %d ", sqn);
sqn++;
if(magic==1 && magic1==1 && magic2==1){
printf(" Magic!\n");
}
else{
printf(" Not Magic\n");
}
}
fclose(file1);
return 0;
}

Related

how to find sum of each value of column in multidimensional array

sorry, im still try to figure out about multiple repetition and array and i need help to find sum of each value of column in multidimensional array.
so i have this input :
2 -> number of tc
3 -> size of array
1 2 3
4 5 6 -> all value of array
7 8 9
4 -> size of array
1 2 3 4
5 6 7 8 -> value of array
9 0 1 2
3 4 5 6
and the output will be :
Case#1: 12 15 18
Case#2: 18 12 16 20
and here is my code :
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&m);
int o[m][m],sum[m][m];
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
scanf("%d",&o[i][j]);
sum[i][j]=o[i][j]+o[i+1][j+1];
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
printf("Case #%d: %d ",i,sum[i][j]);
}
printf("\n");
}
}
return 0;
}
First the code :
#include <stdio.h>
int main () {
int cases;
printf ("\nCases Count? : ");
scanf ("%d", &cases);
for (int cid = 0; cid < cases; ++cid) {
int size;
printf ("\nMatrix Size : ");
scanf ("%d", &size);
long sum [size]; // if long has more space than int on your machine, else use long long
for (int col = 0; col < size; ++col) // reset sums before next case
sum[col] = 0;
// we don't need to store matrix, as we're not re-using it
for (int row = 0; row < size; ++row) {
for (int col = 0; col < size; ++col) {
int value;
scanf ("%d", &value);
sum[col] += value; // add the value to respective column total
}
}
printf ("Case #%d: ", cid + 1);
for (int col = 0; col < size; ++col)
printf ("%ld ", sum[col]);
printf ("\n");
}
return 0;
}
Warning: scanf() fails if you input a string instead of numbers. scanf() usage. Lookup how to use fgets() & parse inputs to have more control.
There is no prize for using bare minimum variable names. Use concise yet meaningful variable names, even if you're testing something.
Enable all compiler warnings. For GCC an alias something like alias mygcc='gcc -Wall -Wextra -pedantic -g3 -O2 -fsanitize=address,undefined,leak -Wshadow'.
I have a few suggestions to help you along. First, the first, second, and fourth for loops use the same indexing variable i. This will cause issues with the first for loop as the variable i is being changed by the others. I suggest you first create a program that only works with a single matrix then, once it works correctly, expand it to handle multiple matrices. This will reduce the number of for loops you have to manage while figuring out the indexing. Second, the sum array doesn't have the correct size. It looks like it should be sum[n][m] instead of sum[m][m]. Lastly, to get the output you want, you should move the output for loop outside of the first for loop. Like this:
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++){
...
for(int i=1;i<=m;i++){
...
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
printf("Case #%d: %d ",i,sum[i][j]);
}
printf("\n");
}

how to continously scan for the amount of numbers inside of an array

I currently am having a small trouble in my code, I am supposed to make a program that adds / sums all numbers inside of an array, while I have no problem in doing that, I currently have a problem with the part in which you are supposed to scan the numbers to be put in the array, here are the example of the input
3
5
1 2 3 4 5
8
1 2 3 4 5 6 7 8
9
1 2 3 4 5 6 7 8 9
What this means is that, the user inputs number "3" as it means to create 3 arrays, the number "5" afterward means to put 5 numbers inside of the array (1 2 3 4 5), after the user has inputted the numbers inside of an array, the user inputs "8" which means to make another array consisting of 8 numbers, and then putting numbers into the array again, and so on.
However I am having a problem in which after inputting all the numbers in the array that consists of 5 number, the program instead inputs 5 number into another array again (instead of asking the amount of numbers to be put inside of another array), so instead the number "8 1 2 3 4" gets inputted in another array, and I did not know which part I did wrong.
Here are my C code :
#include <stdio.h>
int main(){
int x, y;
int i;
int n;
int c=1;
int count=0;
int sum=0;
scanf("%d", &y); //this determines the amount of array to be inputted
scanf("%d", &x); //this determines the amount of numbers to be inputted inside of an array
int line[x];
for(int i=0; i<y; i++){
sum=0;
for(int i=0; i<x; i++){
scanf("%d", &line[i]); //scan number for the array
sum += line[i];
}
printf("Case #%d: %d\n", c, sum);//output of all sum
c++;
}
}
You need to read the size for each array - currently you only read it once.
e.g.:
int numLines;
scanf("%d", &numLines);
for(int lineIdx = 0; lineIdx < numLines; lineIdx++) {
// read the number of elements for each array
int numNumbers;
scanf("%d", &numNumbers);
int line[numNumbers];
for(int i = 0; i < numNumbers; i++) {
scanf("%d", &line[i]);
}
}
Additionally you can avoid storing the individual numbers, since you're only interested in the sum, e.g.:
int sum = 0;
for(int i = 0; i < numNumbers; i++) {
int number;
scanf("%d", &number);
sum += number;
}
Also you could defer outputting the sums until all inputs have been processed, so it doesn't visually get interleaved into the input.
This would be a possible way to write that program: godbolt
#include <stdio.h>
int main() {
// get the number of arrays we need to read
int numLines;
scanf("%d", &numLines);
// The sums of each array
int sums[numLines];
for(int lineIdx = 0; lineIdx < numLines; lineIdx++) {
// read the number of elements for each array
int numNumbers;
scanf("%d", &numNumbers);
// sum up all the numbers of the array
sums[lineIdx] = 0;
for(int i = 0; i < numNumbers; i++) {
int number;
scanf("%d", &number);
sums[lineIdx] += number;
}
}
// after all arrays have been entered,
// output the sums for each case:
for(int lineIdx = 0; lineIdx < numLines; lineIdx++) {
printf("Case #%d: %d\n", lineIdx, sums[lineIdx]);
}
}

transpose square matrix with pointer in C. wrong output

The goal is to print the transpose of the 'Matrix'.
To create square matrix, I got 'row' from the keyboard.
row is same with column so I only declared 'row'.
the problem I need help is right below ↓
/*input*/
5 4 1
9 0 1
6 5 7
/*output I want*/
5 9 6
4 0 5
1 1 7
/*wrong output I get*/
0 4 -30838770
0 7 2
0 5 7
And here is my code. Matrix in each function must be called by reference. I also want to know if I got it right.
//code start
int Generate(int row, int (*Matrix)[row])
{
srand(time(NULL)); //make random number
int i, j;
printf("Matrix = ");
for(i=0; i<row; i++){
for(j=0; j<row; j++){
Matrix[i][j] = (rand() % 10); //insert random number from 0 to 10
printf("%d ", Matrix[i][j]); //print matrix before transposing
}
printf("\n");
}
return 0;
}
void Transpose(int row, int (*Matrix)[row])
{
int i, j;
for(i=0; i<row; i++){
for(j=0; j<row; j++){
int transpose[i][j];
transpose[i][j] = Matrix[j][i];
printf("%d ", transpose[i][j]);
}
printf("\n");
}
}
int main() {
int input; //for switch case
int row = 0; //row has to be 2 or 3
int Matrix[row][row]; //2d array. largest index should be Matrix [row-1][row-1]
while(1){
scanf("%d", &input);
switch(input){
case 1: // Generate random square matrix
scanf("%d", &row); //insert row
Generate(row, Matrix);
break;
case 2: //transpose matrix
Transpose(row, Matrix);
break;
default:
return 0;
}
}
}
//code end
I'm new to this community so I'm not sure I gave you all the information needed.
Please let me know the lines you don't understand because I really want to get this code work.
I'm waiting for your help!
Your program is trying to print the transpose, so you don't need to store anything. remove all the stuff with transpose[i][j], and just print Matrix[j][i]. As pointed out in the comments, you are allocating (on the stack) a new matrix of shape ixj at each iteration, which makes no sense.

Input values from scanf but prints different values

I input the values from scanf but when i print them, all the columns have the last row's values.
#include <stdio.h>
int main(){
int N, M;
int A[N][M];
int T[N][M];
int i,j;
printf("Insert number of rows and columns: ");
scanf("%d %d",&N,&M);
printf("\nInsert the matrix\n");
for(i=0; i<N; i++){
for(j=0; j<M; j++){
scanf("%d", &A[i][j]);
}
}
printf("\nInserted matrix:\n");
for(i=0; i<N; i++){
for(j=0; j<M; j++){
printf("%d ",A[i][j]);
}
printf("\n");
}
return 0;
}
I've tried checking if it's a index problem and printing each element with its coordinate but that seems to be fine, the problem must be somewhere in the scanf.
Input:
Insert number of rows and columns: 3 3
Insert the matrix
1 2 3
4 5 6
7 8 9
output:
Inserted matrix:
7 8 9
7 8 9
7 8 9
Turn on compiler warnings. Any decent compiler will warn you that in:
int N, M;
int A[N][M];
N and M are not initialized. Because they are not initialized, you do not know what int A[N][M]; will do. The array dimensions must be known when the declaration is reached.
You can move int A[N][M]; and int T[N][M]; to after the scanf that reads N and M.
Note that declaring arrays with variable lengths is not suitable for general code. It can be used for simple school assignments, but you should eventually progress to using malloc and other techniques. (Variable length arrays can also be used where the size is known to be within certain limits.)
the following proposed code:
cleanly compiles
performs the desired functionality
fails to check for errors when calling scanf()
and now, the proposed code:
#include <stdio.h>
int main( void )
{
int N, M;
printf("Insert number of rows and columns: ");
scanf("%d %d",&N,&M);
int A[N][M];
//int T[N][M];
int i,j;
printf("\nInsert the matrix\n");
for(i=0; i<N; i++)
{
for(j=0; j<M; j++)
{
scanf("%d", &A[i][j]);
}
}
printf("\nInserted matrix:\n");
for(i=0; i<N; i++)
{
for(j=0; j<M; j++)
{
printf("%d ",A[i][j]);
}
printf("\n");
}
return 0;
}
When run with the input:
3 3
1 2 3 4 5 6 7 8 9
The output is:
Insert number of rows and columns: 3 3
Insert the matrix
1 2 3 4 5 6 7 8 9
Inserted matrix:
1 2 3
4 5 6
7 8 9
The critical difference between the OPs posted code and this answer is the initialization of 'N' and 'M' before they are used in defining the size of the array: A[N][M]

How to reverse the position of a nested loop output?

I'm a beginner C programmer and a college freshman.
I need a little help here with a test i'm working on here.
I want to make a nested loop that shows a sorted number. Sorta like this:
1
3 2
4 5 6
10 9 8 7
11 12 13 14 15
21 20 19 18 17 16
22 23 24 25 26 27 28
... ... ... and so on, depending the limit of rows you input
I already tried to make a crude trial-and-error test code:
int i;
int j;
int limit;
int number1 = 1;
int number2 = 3;
int spesial = 0;
printf("Input limit : ");
scanf("%d", &limit);
for (i=1;i<=limit;i++)
{
for(j=1;j<=i;j++)
{
if (i%2==0)
{
printf("%d ", number2);
number2--;
}
else
{
printf("%d ", number1);
}
number1++;
}
if (i%2==0)
{
number2=(i*6)-i+(spesial*1);
spesial+=1;
}
printf("\n");
}
I managed to make it sorted to the 7th rows, but the rest are not..
help please...
I want to know if we could actually control the position of the output without sorta crude our way like this.
Also, sorry for my English... I'm not really from an English speaking country and this is my first time posting/question in this site.
Thank you for reading this lengthy question and I hope you have a good day and good night.
https://ideone.com/yCxpHo:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int rows;
int i, j;
int n = 0;
printf ("How many rows do you want? ");
if (scanf("%d", & rows) != 1 || rows < 1) return EXIT_FAILURE;
printf ("\n");
for (i = 1; i <= rows; ++ i) {
for (j = 0; j < i; ++ j) {
printf ("%4d", n + (i % 2 == 0 ? i - j : j + 1));
}
printf ("\n");
n = n + i;
}
return EXIT_SUCCESS;
}
It can be more convenient to create another function that will calculate the biggest number of a row (I called it lineMax).
int lineMax(int num){
int cnt=0;
for (int i=1;i<=num;i++)
cnt+=i;
return cnt;
}
void main(){
int i,j,limit;
printf("Input limit : ");
scanf("%d", &limit);
for(i=1;i<=limit;i++){
if(i%2==0){ //right to left
for(j=lineMax(i);j>=lineMax(i-1)+1;j--)
printf("%d ",j);
}
else{ //left to right
for(j=lineMax(i-1)+1;j<=lineMax(i);j++)
printf("%d ",j);
}
printf("\n");
}
}
You are making a lot of special cases with number1, number2 and special. This will not work for bigger numbers.
One way is to calculate count which will give you the value to start from in each loop of j. count += i and then every time print count -j
count = 0;
for (i=1;i<=limit;i++)
{
count += i;
for(j=0;j< i;j++)
{
printf ("%d ",count-j);
}
printf("\n");
}

Resources