I need to allocate 0 , at random, within a matrix
like a:
Matrix a Matrix b
1 3 5 1 0 5
6 7 2 --setBoard-> 0 0 2 // counterZeros = 5
9 3 1 9 0 0
but i need to handle the number of zeros, for the returned matrix,
my idea is to iterate until it reaches the requested number of zeros (in this case would be 5 zeros ) and break the loop(while(breaker==0))
i have this code:
void setBoard(int **boardMatrix, int N){
int counterZeros = 0;
int i, j;
int breaker = 0;
while(breaker == 0) {
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if(boardMatrix[i][j] != 0) {
if(i == randomNum(N)) { // generate random number [0,N]
boardMatrix[i][j] = 0;
counterZeros++;
if(counterZeros = 5) breaker = 1;
}
}
}
}
}
printf("\n Numero vacias: _%d_\n", counterZeros);
}
example call:
int **matrix = (int**)malloc(N*sizeof(int*)); //matrix 3x3
for (i=0;i<N;i++) matrix[i] = (int*)malloc(N*sizeof(int));
genBoard(matrix,3); //here make the matrix to "matrix a"
printM(matrix);
setBoard(matrix,3); //after this function should return the matrix with the given number of zeros ( "5" ) "matrix b"
printM(matrix);
when I called the function , the counterZeros reaches "5" shown by the print , but the matrix dont have "5" zeros
Your problem is in the loop condition, while (breaker == 5) will run only if breaker is 5. Also,
if(counterZeros = 5) breaker=1;
Comparission is invalid and you would be assigning breaker the value of 1 everytime.
Related
I need to check if I can find inside of given matrix size of 5*8
a matrix that has a transpose and if there is more than one I must find the biggest one.
example of a given matrix
1 2 0 3 2 1 0 7
2 3 4 1 2 3 4 5
3 4 6 2 5 6 7 6
4 5 7 3 6 8 9 8
6 7 1 4 7 9 0 9
in this matrix we can find a matrix 4x4
that has transpose and its the biggest matrix in the main matrix
1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 0
#include <stdio.h>
#define M 4
#define column 5
#define row 8
int main()
{
int matrixA[5][8];
printf("please enter a matrix to check if there is a transpose matrix\n");
for (int i = 0; i < column; i++)
{
for (int j = 0; j < row; j++)
{
printf("please enter %d row and %d column: ", i + 1, j + 1);
scanf("%d", &matrixA[i][j]);
}
}
transpose(matrixA, column, row);
}
void transpose(int A[][row], int c, int r)
{
int matrixAT[M][M];
for (int size = r; size > 0; size--)
{
for (int j = 0; j < c - size + 1; j++)
{
for (int b = 0; b <= r - size; b++)
{
printf("Checking Matrix at row: %d , column: %d ,size: %dx%d", j, b, size, size);
for (int k = j, w = 0; k < size + j; k++, w++)
{
for (int l = b, z = 0; l < size + b; l++, z++)
{
matrixAT[w][z] = A[k][l];
}
printf("/n");
}
if (IsSymmetric(matrixAT, size))
printf("Matrix found");
}
}
}
}
int IsSymmetric(int mat[M][M], int size)
{
int flag = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (mat[i][j] == mat[j][i]) flag++;
}
}
return flag == size * size ? 1 : 0;
}
this is my code i dont know what im doing wrong
Your IsSymmetric is slow as it always check all elements why not stop on first inequality instead? Also copying it to temp array again and again ...
The main problem is You are not checking every position and size as you call transpose(matrixA, column, row); only once outside the loops ...
Also your main does not return anything and its declared as int ...
I would start with brute force like this:
#define column 5
#define row 8
int IsSymmetric(int mat[column][row], int i0,int j0,int size) // check n*n sub matrix at i0,j0 no need to copy again and again to temp array
{
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
if (mat[i0+i][j0+j] != mat[i0+j][j0+i]) return 0;
return 1;
}
int min(int a,int b){ return (a<b)?a:b; } // not sure if min is present in your environment if is comment this line out
int main()
{
int matrixA[5][8];
...
for (int i = 0; i < column; i++)
for (int j = 0; j < row; j++)
for (int n = 1; n <= min(column-i,row-j); n++)
if (IsSymmetric(matrixA,i,j,n))
{
// here do what you want with the i,j,n*n sub matrix
// like remember position and size for the biggest n
}
...
return 0; // return value as you declared int main
}
Hope I did not make any typo in here as I just wrote this into answer editor from your original code.
How ever as you can see its O(n^4) complexity (on average O(n^3)) which is really slow. However for your small matrix its not a problem.
In case you need something faster then we need to know more about the data ... for example what is the range of the values? Some hints:
on positive IsSymmetric test one cell bigger submatrix without testing the previous elements again (recursively increasing diagonal).
use histogram to detect values that might be only on diagonals (appear once globally or odd times locally)
Using the incremental symmetry test results in O(n^3) solution:
//---------------------------------------------------------------------------
#define column 5
#define row 8
//---------------------------------------------------------------------------
void submatrix_print(int mat[column][row], int i0,int j0,int n,int m)
{
int i,j;
printf("%i*%i at %i,%i\r\n",n,m,i0,j0);
for (i=0;i<n;i++,printf("\r\n"))
for (j=0;j<m;j++)
printf("%1i ",mat[i0+i][j0+j]);
}
//---------------------------------------------------------------------------
void submatrix_print_transposed(int mat[column][row], int i0,int j0,int n,int m)
{
int i,j;
printf("%i*%i at %i,%i\r\n",n,m,i0,j0);
for (i=0;i<m;i++,printf("\r\n"))
for (j=0;j<n;j++)
printf("%1i ",mat[i0+j][j0+i]);
}
//---------------------------------------------------------------------------
int min(int a,int b){ return (a<b)?a:b; }
int submatrix_symmetric(int mat[column][row], int i0,int j0) // returns biggest symetric submatrix size >=1 found at i0,j0
{
int i,n,N;
N=min(column-i0,row-j0); // max size that still fits into matrix
for (n=2;n<N;n++) // test all sizes above 1
for(i=0;i<n-1;i++) // only test newly added cells to last sub matrix
if (mat[i0+n-1][j0+i]!=mat[i0+i][j0+n-1])
return n-1; // first non match means last tested size i svalid
return n; // no mismatches mean full size is valid
}
//---------------------------------------------------------------------------
int main()
{
int mat[5][8]=
{
1,2,0,3,2,1,0,7,
2,3,4,1,2,3,4,5,
3,4,6,2,5,6,7,6,
4,5,7,3,6,8,9,8,
6,7,1,4,7,9,0,9,
};
submatrix_print(mat,0,0,5,8);
// submatrix_print_transposed(mat,0,0,5,8);
int i,j,n,i0=0,j0=0,n0=0;
for(i=0;i<column;i++)
for(j=0;j<row;j++)
{
n=submatrix_symmetric(mat,i,j);
if (n0<n){ n0=n; i0=i; j0=j; }
}
submatrix_print(mat,i0,j0,n0,n0);
return 0;
}
//-------------------------------------------------------------------------
The result of the code is:
5*8 at 0,0 // input matrix
1 2 0 3 2 1 0 7
2 3 4 1 2 3 4 5
3 4 6 2 5 6 7 6
4 5 7 3 6 8 9 8
6 7 1 4 7 9 0 9
4*4 at 1,3 // biggest symmetric sub matrix found
1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 0
you can make a function that check if the matrix ican be transposed or no
and another function that take evry time a part from the main matrix and you move it everytime and check it with 1st function
example :
1st matrix :m[1][1] starting from zero
1 2
2 3
2 matrix :m[2][2] starting from one
2 0
3 4
then when you finish with 2 demension matrix you go to 3
till the end
i hope you understand me and sorry for my bad english
I create a program that get the input of array element size of 10. Everything getting will with the sum of even and odd number. but when it comes to the inverse it didn't work.
i created two arrays where the first getting the value from the user and second copying the element starting from end of the first array..
#include <stdio.h>
int main (){
int array[10] , i , odd =0 , even =0;
int array1[10],b;
for (i=0 ; i < 10 ; i ++){
printf("Insert number %d: ",i);
scanf("%d",&array[i]);
}
for (i=0; i < 10 ; i++){
if ( array[i] % 2 == 0){
even = even + array[i];
}
else
odd = odd + array[i];
}
printf("\n The Sum of Even Numbers in this Array = %d ", even);
printf("\n The Sum of Odd Numbers in this Array = %d ", odd);
for ( i = 10 , b =0; i>0; i-- , b++)
{
array1[b] = array[i];
}
printf("\nReverse Order:\n");
for ( b = 0 ; b< 10;b++ )
{
printf(" %d",array[b]);
}
return 0;
}
The input will be: 2 3 5 4 6 12 3 7 4 9
What I expect the out put for the reverse is: 9 4 7 3 12 6 4 5 3 2
But it gave me same value as : 2 3 5 4 6 12 3 7 4 9 .
Any Idea for how doing this reverse.?
In addition to the answer by #Yunnosch that identifies the problems in your current implementation, you can refactor (rearrange) your code to sum even and odd and reverse array into array1 in a single loop. The only other loop you need is the loop to iterate over array1 outputting the reversed array.
With a bit of re-arranging, you could do something similar to:
#include <stdio.h>
int main (void) {
int array[] = { 2, 3, 5, 4, 6, 12, 3, 7, 4, 9 }, /* array */
array1[sizeof array/sizeof *array], /* array1 */
even = 0, odd = 0; /* even/odd */
size_t n = sizeof array/sizeof *array; /* no. elem in array */
for (size_t i = 0; i < n; i++) { /* loop over each element in array */
array1[i] = array[n - i - 1]; /* reverse into array1 */
if (array[i] & 1) /* check if odd (bit-0 == 1) */
odd += array[i]; /* add value to odd */
else /* even */
even += array[i]; /* add value to even */
}
/* output results */
printf ("even sum: %d\nodd sum : %d\n\nreversed: ", even, odd);
for (size_t i = 0; i < n; i++)
printf (" %d", array1[i]);
putchar ('\n');
}
(note: you can either use if (array[i] % 2) or if (array[i] & 1) to test whether the element is odd or even. Anding with 1 simply checks whether bit-0 is 1, if it is, it's an odd number. Modern compilers will optimize to remove the division inherent to modulo, so whichever you prefer should pose no penalty)
Example Use/Output
$ ./bin/revarr
even sum: 28
odd sum : 27
reversed: 9 4 7 3 12 6 4 5 3 2
Look things over and let me know if you have questions.
You are outputting the array which you never tried to inverse.
printf(" %d",array[b]);
should be
printf(" %d",array1[b]);
Aside, the input by David C. Rankin:
Also for ( i = 10 ... and array1[b] = array[i]; assigns from beyond the end of array. It should e.g. better be
for ( i = 10 , b =0; i>0; i-- , b++)
{
array1[b] = array[i-1];
}
I'm having the following problem:
A park that have the form of a m x n board. There are k kinds of trees (1 <= k <= 100). The park is divided into m x n cells and each cell, they'll plant a tree. Now, on the map, each cell of the park have an integer i inside if the i-th kind of tree is planted in it, or a 0 if no tree is planted in it. A line of cells is considered "good" if it has at least t trees of same types, (and they must be on the same either line or column). Count the number of trees that is not in a "good" line.
Input: Integers m, n, t and an m x n array of integers represent the map.
Output: Number of trees that is not in a "good" line.
Example:
Input:
5 6 3
1 3 3 3 3 4
1 2 3 2 0 4
3 2 2 2 4 4
1 0 0 2 4 0
1 2 3 0 4 4
Output: 10
Explanation: The bold numbers are the trees that is not in a good line.
1 3 3 3 3 4
1 2 3 2 0 4
3 2 2 2 4 4
1 0 0 2 4 0
1 2 3 0 4 4
My idea is to check for each element in the array. If it is satisfied then I'll move to the nearest element outside the "good" line. Else, it will just move to the next element on the same line, or if the line is ended then the next element on the column.
Here is my code
#include <stdio.h>
#define maxn 120
int a[maxn][maxn], m, n, t;
int check(int *i, int *j){
int k, cnt_r, cnt_c;
cnt_r = 0;
//jump to the nearest cell that is not in good line
for(k = *i + 1; k < m; k++){
if(a[*i][*j] == a[k][*j]) cnt_r++;
if(cnt_r >= t){
*i = k;
return 1;
}
}
cnt_c = 0;
for(k = *j + 1; k < n; k++){
if(a[*i][*j] == a[*i][k]) cnt_c++;
if(cnt_c >= t){
*j = k;
return 1;
}
}
return 0;
}
//check if this is the last square or not
int lastSq(int r, int c){
return (r == n - 1 && c == n);
}
int main(){
int res = 0, i, j, pos_r = 0, pos_c = 0;
scanf("%d%d%d", &m, &n, &t);
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
scanf("%d", &a[i][j]);
while(!lastSq(pos_r, pos_c)){
if(a[pos_r][pos_c] == 0){
if(pos_c < n - 1) pos_c++;
else if(pos_r < n - 1){
pos_c = 0;
pos_r++;
}
}
if(!check(&pos_r, &pos_c)){
res++;
if(pos_c < n - 1) pos_c++;
else{
pos_c = 0;
pos_r++;
}
}
}
printf("%d", res);
}
But it doesn't print any output. The only thing I have is 0xC0000005. Can someone please check where did I make a mistake and provide me a direction? Thanks.
#include <stdio.h>
void main(){
int i, j, n;
int num[5];
int serial;
for(i=0; i<5; ++i){
scanf("%d",&num[i]);
if(num[i]==num[i-1])
serial=i;
else
continue;
}
printf("Serial number of equal numbers next to each other:%d. %d.", serial-1, serial);
}
This may be hard to understand because I'm not a native English speaker.
If the numbers next to each other are equal the program should print the serial number of those numbers.
For example:
Input: 1 2 3 7 7 7 6;
Output: 3. 4. 5.
Input: 5 5 5 5 5
Output: 0. 1. 2. 3. 4.
I made some changes now it prints the serial of two equal numbers.
I: 1 2 2 3 4 - O: 1. 2.
But what if all the numbers are equal?
// ...
// deal with index 0
if (num[0] == num[1]) printf("0. ");
// deal with indexes 1 .. N - 2
for (int k = 1; k < n - 1; k++) {
if ((num[k - 1] == num[k]) || (num[k] == num[k + 1])) {
printf("%d. ", k);
}
}
// deal with index N - 1
if (num[n - 2] == num[n - 1]) printf("%d. ", n - 1);
// ... possibly with a printf("\n"); somewhere
You can solve this without storing the numers in an array, but you must keep track of how many equal numbers have been read before reading the present one:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i = 0; // running index
int prev = 0; // previously read number
int iprev = 0; // start of range of equal numbers previously read
int n; // currently read number
while (scanf("%d", &n) == 1) {
if (n != prev) {
if (i - iprev > 1) {
while (iprev < i) printf("%d\n", iprev++);
}
iprev = i;
prev = n;
}
i++;
}
if (i - iprev > 1) {
while (iprev < i) printf("%d\n", iprev++);
}
return 0;
}
You consider stretches of equal numbers only after you read a number that terminates the current range of equal numbers. When all numbers are different, the size of that range is 1 and we don't print anything. If the range is larger than 1, print all indices in question.
Because you don't notice a change after reading the last number, you must check the last range separately after the main loop.
If you can put a non-numeric character in the [0] element of your array, you won't need a different test for the first element
int main (void)
{
/* non-numeric in position 0 of data array */
char myList[] = {'.','1','2','2','3','4','4','4','5','6','6'};
int listSz = strlen(myList) -1;
int n;
/* check everything except last */
for (n = 1; n < listSz; n++) {
if(( myList[n] == myList[n +1]) || ( myList[n] == myList[n -1] )) {
printf("%d . ", n);
}
}
/* check last */
if( myList[listSz] == myList[listSz -1] ) {
printf("%d", n);
}
printf("\n");
}
Output: 2 . 3 . 5 . 6 . 7 . 9 . 10
I have c program problem to print the ring type output.
When user enter the number 5, then program output is look like;
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
I use following logic but i really failed i not have any idea.
int main()
{
int a[50],i,j=0,n,k;
printf("Enter the number=");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
if(i>n)
{
j=j+5;
}
else if(i>((2*n)-1))
{
j--;
}
else if(i>((3*n)-2))
{
j=j-5;
}
else if(i>(4*n-4))
{
j++;
}
}
}
Sorry for asking whole program logic but
,I really dont have any idea,Please help me.....
here's what you are looking for
#include <stdio.h>
#define max 25
int main()
{
int spiral[max][max] = {{0}}; // initializing array with 0
int r, c, i = 0, j = -1, count = 1;
printf("\nEnter the row and column for spiral matrix:\n");
scanf("%d%d", &r, &c);
while (count <= r * c) // this loop executes till all the blocks of
{
// array r*c are filled with 0
while (j < c - 1) // Filling the location from left to right
{
// with value of variable count
if(spiral[i][j+1]!=0) // Here we are checking if that location
break; // is already occupied
spiral[i][++j] = count++;
}
while (i < r - 1) // Filling the location from top to bottom
{
if (spiral[i+1][j] != 0)
break;
spiral[++i][j] = count++;
}
while (j > 0) // Filling the location from right to left
{
if(spiral[i][j-1] != 0)
break;
spiral[i][--j] = count++;
}
while (i > 0) // Filling the column from bottom to top
{
if (spiral[i-1][j] != 0)
break;
spiral[--i][j] = count++;
}
}
for (i = 0 ; i < r ; i++)
{
for (j = 0 ; j < c ; j++)
{
printf("%3d",spiral[i][j]); // print the matrix
}
printf("\n");
}
return 0;
}
reference is here from more details
A simple way to solve this problem is to allocate an array of size N*N and to populate it with a straight forward loop that follows the spiral. Then you can print the array contents N elements per row.