Matrix multiplication - c

I can't understand where is the mistake. Help me correct it please. The output is coming as all the elements of resultant matrix being zero.
#include<stdio.h>
#include<conio.h>
int main()
{
int a[5][5],b[5][5],c[5][5],i=0,j=0,row1,col1,row2,col2,row3,col3,s=0,k=0,l=0;
printf("Enter no. of rows and no. of columns of first matrix:\n");
scanf("%d %d",&row1,&col1);
printf("Enter no. of rows and no. of columns of second matrix:\n");
scanf("%d %d",&row2,&col2);
if(col1==row2)
{
row3=row1;
col3=col2;
}
else
{
printf("Not possible!");
exit(1);
}
printf("Enter elements of first matrix:\n");
for(i=0;i<row1;i++)
{
for(j=0;j<col1;j++)
{
scanf("%d",&a[i][j]);
}
}
printf("Enter elements of second matrix:\n");
for(i=0;i<row2;i++)
{
for(j=0;j<col2;j++)
{
scanf("%d",&b[i][j]);
}
}
i=0;
j=0;
for(k=0;k<row3;k++)
{
for(l=0;l<col3;l++)
{
while(i<row3 || j<col3)
{
//printf("Hi");
s=s+a[i][j++]*b[i++][j];
//printf("%d\n",s);
}
}
printf("%d\n",s);
c[k][l]=s;
s=0;
}
printf("Sum matrix is:\n");
for(k=0;k<row3;k++)
{
for(l=0;l<col3;l++)
{
printf("%d ",c[k][l]);
}
printf("\n");
}
getch();
}
I have included comments of printing in the while loop so as to debug but it's not helping.

You are setting the result outside of your column loop, so you only set one result per row. Change the code to this by moving those 3 lines inside the brace:
for(k=0;k<row3;k++)
{
for(l=0;l<col3;l++)
{
i = 0; j = 0;
while(i<row3 || j<col3)
{
//printf("Hi");
s=s+a[k][j++]*b[i++][l];
//printf("%d\n",s);
}
// THIS CODE HAS MOVED:
printf("%d\n",s);
c[k][l]=s;
s=0;
}
}
Also, your addition needs to use the k and l indices, so that you move along a row of a[][] given by k and a column of b[][] given by l:
s=s+a[k][j++]*b[i++][l];

You forgot to initialize i and j inside the loop where you add the two matrices.
According to your code add.
i=0; j=0 inside the double for loop for addition.
Hope this helps

Related

Printing asterisk pattern using nested for loops in C

This code is intended to print a pattern with asterisk like this
If a number is entered such as 5
Then the program should print the following pattern. It should print * in order according to the number given and then decreasing
*****
****
***
**
*
But it is printing only one line. Please tell me what is the fault here.
#include<stdio.h>
int main()
{
int lines,lines2;
printf("Enter the number of lines : ");
scanf("%d",&lines);
lines2=lines;
for(;lines>0;lines--) {
for(;lines2>0;lines2--){
printf("*");
}
}
printf("\n");
return 0;
}
First: The following line should be placed between two loop:
lines2=lines;
Second: The following line should be placed before the { of outer loop:
printf("\n");
The Final solution is:
#include<stdio.h>
int main()
{
int lines,lines2;
printf("Enter the number of lines : ");
scanf("%d",&lines);
for(;lines>0;lines--)
{
lines2=lines;
for(;lines2>0;lines2--)
{
printf("*");
}
printf("\n");
}
return 0;
}
lines2=lines;
for(;lines>0;lines--)
{ for(;lines2>0;lines2--)
You only initialize lines2 once BEFORE the outer loop; that is why past the first line it is always zero. You should reset it per each line, assigning to current value of lines. This one is probably what you wanted to do:
for(; lines > 0; --lines) {
for(lines2 = lines; lines2 > 0; --lines2) {
See this!
It works!
#include<stdio.h>
main()
{ int lines,lines2;
printf("Enter the number of lines : ");
scanf("%d",&lines);
lines2=lines;
for(;lines>0;lines--)
{ for(lines2=lines;lines2>0;lines2--)
{ printf("*");
}
printf("\n");
}
}
You just changed some lines' places. You need to put newline into first loop:
int main() {
int lines,lines2;
printf("Enter the number of lines : ");
scanf("%d", &lines);
for(;lines>0;lines--) {
lines2=lines;
for(;lines2>0;lines2--){
printf("*");
}
printf("\n");
}
return 0;
}

Program to remove the duplicate elements from an array in c

I've tried to write a program that removes the duplicate values from an array. I've partly managed to do so since my program is able to remove any ONE of the numbers which are repeated TWICE in the array. So the problem is that if a number is repeated thrice only one of the number is removed, i.e. the other two is still left in the array, also if more than one number is repeated even then only the number which comes first in the array is removed. I really cannot understand what's wrong with my code and why is it unable to remove numbers that are repeated more than two times. I've already surfed through the internet regarding this issue and though I got different ways to remove the duplicate elements, I still don't know what's wrong with my code.
#include <stdio.h>
#include <stdlib.h>
int dup(int [],int);
int main()
{
int i,n,index,a[20];
printf("Enter n value \n");
scanf("%d",&n);
printf("Enter array values \n");
for(i=0;i<n;++i)
scanf("%d",&a[i]);
for(i=0;i<n;++i)
{
index=dup(a,n);
if(index==-1)
{
printf("No duplicate elements");
break;
}
else
{
a[index]=0;
for(i=index;i<n;i++)
a[i]=a[i+1];
n-=1;
}
}
printf("Output: \n");
for(i=0;i<n;++i)
printf("%d\n",a[i]);
return (EXIT_SUCCESS);
}
int dup(int a[],int size)
{
int i,j,pos=-1;
for(i=0;i<size;i++)
{
for(j=i+1;j<size;j++)
{
if(a[i]==a[j])
{
pos=j;
return pos;
}
}
}
if(pos==-1)
return pos;
}
OUTPUT
Enter n value
5
Enter array values
12
24
3
12
24
Output:
12
24
3
24
It clearly fails to remove the other repeated element "24". Also if a number was repeated thrice only one of the number would be removed.
for(i=0;i<n;++i) // <-------------------------------------- for i
{
index=dup(a,n);
if(index==-1)
{
printf("No duplicate elements");
break;
}
else
{
a[index]=0;
for(i=index;i<n;i++) // <--------------------------- for i
a[i]=a[i+1];
n-=1;
}
}
You are using the same loop variable for two loops, one nested inside the other. This cannot work. Use different variables. Live demo.
The Problem seem to lie in the if condition in second loop.
for (k = j; k < size; k++) {
arr[k] = arr[k + 1];
}
Simply put this piece of code after your if condition
if(a[i]==a[j])
and it will work.
My mistake, at first glence I thought you had problem with n after running this it worked.
#include <stdio.h>
#include <stdlib.h>
int dup(int [],int);
int main()
{
int i,n,index,a[20], count;
printf("Enter n value \n");
scanf("%d",&n);
count = n;
int j;
printf("Enter array values \n");
for(i=0;i<n;++i)
scanf("%d",&a[i]);
for(i=0;i<n;++i)
{
index=dup(a,n);
if(index==-1)
{
printf("No duplicate elements");
break;
}
else
{
a[index]=0;
for(j=index;j<n;j++)
a[j]=a[j+1];
n-=1;
}
}
printf("Output: \n");
for(i=0;i<n;++i)
printf("%d\n",a[i]);
return (EXIT_SUCCESS);
}
int dup(int a[],int size)
{
int i,j,pos=-1;
for(i=0;i<size;i++)
{
for(j=i+1;j<size;j++)
{
if(a[i]==a[j])
{
pos=j;
return pos;
}
}
}
if(pos==-1)
return pos;
}
OUTPUT
Enter n value
5
Enter array values
12
24
3
12
24
Output:
12
24
3
You should name your iterator variables better so you might not confuse them in nested loops, or as you do, use the same twice in a nested loop.
This skips all variables after your first removal.
and you don't have to do this
if(pos==-1)
return pos;
skip the if as it is not necessary and if at this position posis not -1then you would have no return which would be UB I think.

How to find the maximum product of two prime numbers in an array?

#include <stdio.h>
int final[3];
int checkprime(int n,int loopcount)
{
int flag=0,m;
for(m=2; m<=loopcount; m++)
{
if(n%m==0 && n!=2)
{
flag=1;
return 0;
break;
}
else if(n==2)
{
flag=0;
break;
}
}
if(flag==0)
{
return 1;
}
}
int main()
{
int test_no,n,i,j,k,m,max=1,loopcount,product=1,max_available=0,count=0;
scanf(" %d",&test_no);
for(i=0; i<3; i++)
{
scanf(" %d",&n);
int array[n];
for(j=0; j<n; j++)
{
scanf(" %d",&array[n]);
loopcount=array[n]/2;
if(max<loopcount)
{
max=loopcount;
}
}
loopcount=max;
max=array[0];
for(j=0; j<n; j++)
{
int x=checkprime(array[j],loopcount);
if(x==1)
{
if(array[j]>=max)
{
max=array[j];
}
}
}
product=product*max;
max=1;
for(j=0; j<n; j++)
{
int x=checkprime(array[j],loopcount);
if(x==1)
{
if(array[j]>max && product!=array[j])
{
max=array[j];
max_available=1;
}
else if(array[j]>=max && product==array[j] && max_available==0)
{
max=product;
}
}
if(x==0)
{
count++;
}
}
if(count==n || count==n-1)
{
final[i]=-1;
}
else
{
product=product*max;
final[i]=product;
}
product=1;
}
for(i=0; i<3; i++)
{
printf("%d\n",final[i]);
}
return 0;
}
The above code is not working properly ,I am unable to get the reason behind this , I am finding prime number two times and I have used a variable loopcount so as to find the number of iterations for checking whether the number is prime or not .
I have initially taken an array of size 3 and I am providing 3 inputs with each input of different array size and then I iterate twice for finding the maximum product , If I don't find any prime number , I output -1 on the output screen .
Th first line depicts the total number of inputs which can be viewed as the number of test cases and for each test case , the first line depicts the size of array and the second line depicts the elements present in the array .Please help me to identify the problem , for the first input it is printing -1 but with some issues , Ideally , it should only go to if part
if(count==n || count==n-1)
{
final[i]=-1;
}
but it is going to code snippet of else part ,
else
{
product=product*max;
final[i]=product;
}
This I checked by writing printf statements in the else part , so I am able to get the value printed for the first input ,this is quite confusing since when if part is getting executed then why is the else part getting executed ?And for the rest inputs , it is printing garbage values .
Here is a input set:
3
5
1 4 6 8 10
3
2 2 9
2
156 13
The corresponding output is:
-1
4
169
You should scan array[j] instead of array[n]. nth index is not valid.
int array[n];
for(j=0; j<n; j++)
{
scanf(" %d",&array[n]); /// Problem is here
loopcount=array[n]/2;
if(max<loopcount)
{
max=loopcount;
}
}
Previously, you had a far complex idea. Here is some optimizations done to your code. Feel free to ask anything. Hope it helps :)
#include <stdio.h>
#include <math.h>
int checkprime(int n)
{
int flag=0,m;
for(m=2; m<=sqrt(n); m++)
{
if(n%m==0)return 0;
}
return 1;
}
int main()
{
int test_no,n,i,j,k,m,max=1,loopcount,product=1,max_available=0,count=0;
scanf("%d",&test_no);
for(i=0; i<test_no; i++)
{
scanf(" %d",&n);
int array[n];
for(j=0; j<n; j++)
{
scanf("%d",&array[j]);
}
sort(array); // Use any sort algorithm you wish to sort the array
int _1=1, _2=1;
for(int j=n-1; j>=0; j--){
if(checkprime(array[j])==1){
if(_1==1){
_1=array[j];
}
else if(_1!=1 && _2==1){
_2=array[j];
break;
}
}
}
if(_1==1 && _2==1)printf("-1\n");
else if(_2==1 && _1!=1)printf("%d\n", _1*_1);
else printf("%d\n", _1*_2);
}
return 0;
}

Removing Duplicate values and adding 0 on their place

I have written a code to remove duplicate values and add 0 on there place .
But i feel like my code should be much better than this,if anybody can give a better idea of developing this code.
Please suggest me and advice me.
Input--2,3,4,3,6
output--2,3,4,0,6
Here is my code:
#include<stdio.h>
int main()
{
int a[100],b[100];
int i,j,size;
scanf("%d",&size);
for(i=0;i<size;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<size;i++)
{
b[i]=a[i];
}
for(i=0;i<size;i++)
{
for(j=i+1;j<size;j++)
{
if(a[i]==a[j])
{
b[j]=0;
}
}
}
for(i=0;i<size;i++)
printf("%d\n",b[i]);
return 0;
}
Clear duplicates as they are entered as follows, comparing with the values entered so far:
#include<stdio.h>
int main() {
int a[100];
int i,j,size;
scanf("%d",&size);
for(i=0;i<size;i++)
{
scanf("%d",&a[i]);
for(j=0;j<i;j++){
if(a[j]==a[i]) {
a[i]=0; /* found duplicate among previous entries! */
break;
}
}
}
for(i=0;i<size;i++)
printf("%d\n",a[i]);
return 0;
}
Here is some of my idea:
Solution 1:
Use bit to indicate whether a number occurred yet.
e.g On 32bit machine, 1 int has 32bit, if your number range is 1 ~ 1000, then you need 32 int, you can change it range when you met a larger number, by realloc().
If your number range is small, then it's quite suitable.
Solution 2:
Store sorted numbers in a binary tree, so that you can search quicker.
You can use the single array itself, and mark at the positions where you find a duplicate in it. Something like this.
#include<stdio.h>
int main() {
int a[100];
int i,j,size;
scanf("%d",&size);
for(i=0;i<size;i++) {
scanf("%d",&a[i]);
}
for(i=1; i<size; i++) {
for(j=i-1; j>=0; j--) {
if(a[i]==a[j]) {
a[i]=0;
break;
}
}
}
for(i=0;i<size;i++)
printf("%d ",a[i]);
return 0;
}
Here's an improvement, but I agree it feels like it can be significantly better (Maybe I'll get back to this later...):
#include<stdio.h>
int main()
{
int a[100];
int i,j,size,left;
scanf("%d",&size);
for(i=0;i<size;i++)
{
scanf("%d",&a[i]);
}
left = size;
for(i=0;i<size&&left>1;i++) // If there's only 1 left, it's not a duplicate
{
if(a[i] == 0) // No need to test these, already done
continue;
for(j=i+1,left=0;j<size;j++)
{
if(a[i]==a[j])
{
a[j]=0;
}
if(a[j]!=0)
left++; // If we don't get here, there's nothing left to test
}
}
for(i=0;i<size;i++)
printf("%d\n",a[i]);
return 0;
}
So basically, don't search for 0's ahead of current position, and when searching for anything else count (mark actually) if there is anything left to test.

Odd-Even Sort using cuda Programming

I'm trying to implement odd-even sort program in cuda-c language. But, whenever I give a 0 as one of the elements in the input array, the resulted array is not properly sorted.In other cases, however, it is working for other input.I don't understand what is the problem with the code.Here is my code:
#include<stdio.h>
#include<cuda.h>
#define N 5
__global__ void sort(int *c,int *count)
{
int l;
if(*count%2==0)
l=*count/2;
else
l=(*count/2)+1;
for(int i=0;i<l;i++)
{
if(threadIdx.x%2==0) //even phase
{
if(c[threadIdx.x]>c[threadIdx.x+1])
{
int temp=c[threadIdx.x];
c[threadIdx.x]=c[threadIdx.x+1];
c[threadIdx.x+1]=temp;
}
__syncthreads();
}
else //odd phase
{
if(c[threadIdx.x]>c[threadIdx.x+1])
{
int temp=c[threadIdx.x];
c[threadIdx.x]=c[threadIdx.x+1];
c[threadIdx.x+1]=temp;
}
__syncthreads();
}
}//for
}
int main()
{int a[N],b[N],n;
printf("enter size of array");
scanf("%d",&n);
print("enter the elements of array");
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("ORIGINAL ARRAY : \n");
for(int i=0;i<n;i++)
{
printf("%d ",a[i]);
}
int *c,*count;
cudaMalloc((void**)&c,sizeof(int)*N);
cudaMalloc((void**)&count,sizeof(int));
cudaMemcpy(c,&a,sizeof(int)*N,cudaMemcpyHostToDevice);
cudaMemcpy(count,&n,sizeof(int),cudaMemcpyHostToDevice);
sort<<< 1,n >>>(c,count);
cudaMemcpy(&b,c,sizeof(int)*N,cudaMemcpyDeviceToHost);
printf("\nSORTED ARRAY : \n");
for(int i=1;i<=n;i++)
{
printf("%d ",b[i]);
}
}
Your kernel code had two main errors that I could see:
On the odd phase (for even length array, or even phase for odd length array), your last thread will index out of bounds at c[threadIdx.x+1]. For example, for 4 threads, they are numbered 0,1,2,3. Thread 3 is odd, but if you access c[3+1], that is not a defined element in your array. We can fix this by restricting each phase to work on all threads but the last one.
You were using __syncthreads() inside a conditional statement that would not allow all threads to reach the barrier. This is a coding error. Read the documentation. We can fix this by adjusting what code is inside the conditional regions.
In the main code, your final printout statements were indexing incorrectly:
for(int i=1;i<=n;i++)
that should be:
for(int i=0;i<n;i++)
You also have typo here:
print("enter the elements of array");
I assume that should be printf.
The following code has the above errors fixed, and seems to run correctly for me for arrays up to length 5 (your hardcoded limit on N). Even if you increased N, I'm not sure this would work beyond the size of a warp and certainly would not work beyond the threadblock size, but hopefully you are aware of that already(if not, read the doc link about __syncthreads()).
"Fixed" code:
#include<stdio.h>
#include<cuda.h>
#define N 5
#define intswap(A,B) {int temp=A;A=B;B=temp;}
__global__ void sort(int *c,int *count)
{
int l;
if(*count%2==0)
l=*count/2;
else
l=(*count/2)+1;
for(int i=0;i<l;i++)
{
if((!(threadIdx.x&1)) && (threadIdx.x<(*count-1))) //even phase
{
if(c[threadIdx.x]>c[threadIdx.x+1])
intswap(c[threadIdx.x], c[threadIdx.x+1]);
}
__syncthreads();
if((threadIdx.x&1) && (threadIdx.x<(*count-1))) //odd phase
{
if(c[threadIdx.x]>c[threadIdx.x+1])
intswap(c[threadIdx.x], c[threadIdx.x+1]);
}
__syncthreads();
}//for
}
int main()
{int a[N],b[N],n;
printf("enter size of array");
scanf("%d",&n);
if (n > N) {printf("too large!\n"); return 1;}
printf("enter the elements of array");
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("ORIGINAL ARRAY : \n");
for(int i=0;i<n;i++)
{
printf("%d ",a[i]);
}
int *c,*count;
cudaMalloc((void**)&c,sizeof(int)*N);
cudaMalloc((void**)&count,sizeof(int));
cudaMemcpy(c,&a,sizeof(int)*N,cudaMemcpyHostToDevice);
cudaMemcpy(count,&n,sizeof(int),cudaMemcpyHostToDevice);
sort<<< 1,n >>>(c,count);
cudaMemcpy(&b,c,sizeof(int)*N,cudaMemcpyDeviceToHost);
printf("\nSORTED ARRAY : \n");
for(int i=0;i<n;i++)
{
printf("%d ",b[i]);
}
printf("\n");
}
The usual recital about proper cuda error checking belongs here.

Resources