Strassen multiplication - c program - c

We had to implement strassen's multiplication in a practical session , the code I wrote is given below , as you can see I have used a lot of intermediate matrices .I wanted to know how to return a 2d array from a function so that the code will look cleaner and more understandable , also it will give me some insights on pointers(a weak area for me )i.e say is use a double pointer as return type of sub function (int **sub(args list))
and since my strassen function has prototype strassen(int , int [],int[]..)
When one argument of strassen function is a result of sub function , I get an error saying int (*)[] expected but returning int **
To resolve this I typecasted the result of sub function with int (*)[] but it does not work as expected
Help please ? Thanks !
#include<stdio.h>
#include<stdlib.h>
void add(int n,int a[n][n],int b[n][n],int result[][n])
{
printf("---add---\n");
int i,j;
//int **result = (int **)malloc(n*sizeof(int *));
/*for(i=0;i<n;i++)
result[i] = (int *)malloc(n*sizeof(int));*/
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
result[i][j] = a[i][j] + b[i][j];
printf("%d\t",result[i][j]);
}
printf("\n");
}
//return result;
}
void sub(int n,int a[n][n],int b[n][n],int result[][n])
{
printf("---sub---\n");
int i,j;
/*int **result = (int **)malloc(n*sizeof(int *));
for(i=0;i<n;i++)
result[i] = (int *)malloc(n*sizeof(int));*/
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
result[i][j] = a[i][j] - b[i][j];
printf("%d\t",result[i][j]);
}
}
}
void divide(int n,int a[n][n],int c[n/2][n/2],int i,int j)
{
int i1,i2,j1,j2;
for(i1=0,i2=i;i1<n/2;i1++,i2++)
{
for(j1=0,j2=j;j1<n/2;j1++,j2++)
{
c[i1][j1] = a[i2][j2];
}
}
}
void join(int n,int a[][n],int c[][n/2],int i,int j)
{
printf("join\n");
int i1,i2,j1,j2;
for(i1=0,i2=i;i1<(n/2);i1++,i2++)
{
for(j1=0,j2=j;j1<(n/2);j1++,j2++)
{
a[i2][j2] = c[i1][j1];
printf("c[%d][%d] %d\n",i1,j1,c[i1][j1]);
}
}
}
void multiply(int n,int a[][n],int b[][n],int result[][n])
{
int i,j;
if(n==2)
{
//partial products
printf("base case\n");
int p1 = (a[0][0]+a[1][1])*(b[0][0]+b[1][1]);
int p2 = (a[1][0]+a[1][1])*b[0][0];
int p3 = a[0][0]*(b[0][1]-b[1][1]);
int p4 = a[1][1]*(b[1][0]-b[0][0]);
int p5 = (a[0][0]+a[0][1])*b[1][1];
int p6 = (a[1][0]-a[0][0])*(b[0][0]+b[0][1]);
int p7 = (a[0][1]-a[1][1])*(b[1][0]+b[1][1]);
int c11 = p1 + p4 - p5 + p7;
int c12 = p3 + p5;
int c21 = p2 + p4;
int c22 = p1 + p3 - p2 + p6;
result[0][0] = c11;
result[0][1] = c12;
result[1][0] = c21;
result[1][1] = c22;
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
printf("%d\t",result[i][j]);
}
printf("\n");
}
}
else
{
int a11[n/2][n/2];
int a12[n/2][n/2];
int a21[n/2][n/2];
int a22[n/2][n/2];
int b11[n/2][n/2];
int b12[n/2][n/2];
int b21[n/2][n/2];
int b22[n/2][n/2];
//divide matrices A & B into four parts
divide(n,a,a11,0,0);
divide(n,a,a12,0,n/2);
divide(n,a,a21,n/2,0);
divide(n,a,a22,n/2,n/2);
divide(n,b,b11,0,0);
divide(n,b,b12,0,n/2);
divide(n,b,b21,n/2,0);
divide(n,b,b22,n/2,n/2);
//partial products
int p1[n/2][n/2],p2[n/2][n/2],p3[n/2][n/2],p4[n/2][n/2],p5[n/2][n/2],p6[n/2][n/2],p7[n/2][n/2];
int c11[n/2][n/2],c12[n/2][n/2],c21[n/2][n/2],c22[n/2][n/2];
int i1[n/2][n/2],i2[n/2][n/2];
add(n/2,a11,a22,i1);
add(n/2,b11,b22,i2);
multiply(n/2,i1,i2,p1);
int i3[n/2][n/2];
add(n/2,a21,a22,i3);
multiply(n/2,i3,b11,p2);
int i4[n/2][n/2];
sub(n/2,b12,b22,i4);
multiply(n/2,a11,i4,p3);
int i5[n/2][n/2];
sub(n/2,b21,b11,i5);
multiply(n/2,a22,i5,p4);
int i6[n/2][n/2];
add(n/2,a11,a12,i6);
multiply(n/2,i6,b22,p5);
int i7[n/2][n/2];
int i8[n/2][n/2];
sub(n/2,a21,a11,i7);
add(n/2,b11,b12,i8);
multiply(n/2,i7,i8,p6);
int i9[n/2][n/2];
int i10[n/2][n/2];
sub(n/2,a12,a22,i9);
add(n/2,b21,b22,i10);
multiply(n/2,i9,i10,p7);
//for c11
int r1[n/2][n/2];
int r2[n/2][n/2];
add(n/2,p1,p4,r1); //sub operation
sub(n/2,r1,p5,r2); //sub operation
add(n/2,r2,p7,c11); //main operation
//for c12
add(n/2,p3,p5,c12);
//for c21
add(n/2,p2,p4,c21);
//for c22
int r3[n/2][n/2];
int r4[n/2][n/2];
add(n/2,p1,p3,r3); //sub operation
sub(n/2,r3,p2,r4); //sub operation
add(n/2,r4,p6,c22); //main operation
join(n,result,c11,0,0);
join(n,result,c12,0,n/2);
join(n,result,c21,n/2,0);
join(n,result,c22,n/2,n/2);
printf("---c11---\n");
for(i=0;i<n/2;i++)
{
for(j=0;j<n/2;j++)
{
printf("%d\t",c11[i][j]);
}
printf("\n");
}
printf("---c12---\n");
for(i=0;i<n/2;i++)
{
for(j=0;j<n/2;j++)
{
printf("%d\t",c12[i][j]);
}
printf("\n");
}
printf("---c21---\n");
for(i=0;i<n/2;i++)
{
for(j=0;j<n/2;j++)
{
printf("%d\t",c21[i][j]);
}
printf("\n");
}
printf("---c22---\n");
for(i=0;i<n/2;i++)
{
for(j=0;j<n/2;j++)
{
printf("%d\t",c22[i][j]);
}
printf("\n");
}
/*for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d\t",result[i][j]);
}
printf("\n");
}*/
}
}
int main()
{
int n;
printf("Enter the order of the matrices(power of 2)\n");
scanf("%d",&n);
int i,j;
int a[n][n],b[n][n];
printf("Enter first matrix\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
}
}
printf("Enter second matrix\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&b[i][j]);
}
}
printf("First matrix is \n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d\t",a[i][j]);
}
printf("\n");
}
printf("Second matrix is \n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d\t",b[i][j]);
}
printf("\n");
}
int r[n][n];
multiply(n,a,b,r);
printf("---RESULT OF MULTIPLICATION---\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d\t",r[i][j]);
}
printf("\n");
}
return 0;
}

Related

Error during submitting code on Leet code. (Roman to Integer)

Question Link : https://leetcode.com/problems/roman-to-integer/
My code is running fine on my computer but during my attempts to upload it to leet code it shows the following:
Line 20: Char 18: runtime error: index 10 out of bounds for type 'int [10]' [solution.c]
int romanToInt(char * s){
char a[7]={'M','D','C','L','X','V','I'};
int b[7]={1000,500,100,50,10,5,1};
int x;
x=strlen(s);
int c[x];
for(int i=0;i<x;++i)
{
for(int j=0;j<7;++j)
{
if(s[i]==a[j])
{
c[i]=b[j];
break;
}
}
}
int sum=0;
for(int i=0;i<x;++i)
{
if(c[i]<c[i+1]&&i!=x-1)
{
sum-=c[i];
}
else
{
sum+=c[i];
}
}
//printf("%d",sum);
return sum;
}
Running the same code on my computer using it as a custom function works just fine
#include <stdio.h>
#include<string.h>
int romanToInt(char * s);
void main()
{
char a[100];
char* p;
gets(a);
p=a;
int sum= romanToInt(p);
printf("%d",sum);
}
int romanToInt(char * s){
char a[7]={'M','D','C','L','X','V','I'};
int b[7]={1000,500,100,50,10,5,1};
int x;
x=strlen(s);
int c[x];
for(int i=0;i<x;++i)
{
for(int j=0;j<7;++j)
{
if(s[i]==a[j])
{
c[i]=b[j];
break;
}
}
}
int sum=0;
for(int i=0;i<x;++i)
{
if(c[i]<c[i+1]&&i!=x-1)
{
sum-=c[i];
}
else
{
sum+=c[i];
}
}
//printf("%d",sum);
return sum;
}
Why isn't leet code accepting this result?

Tried Knap snap problem but its not working

#include<stdio.h>
int max(int a,int b)
{
if(a>b)
return a;
return b;
}
void knacksnap(int n,int a[][n+1],int* val,int* weight,int maxweight)
{
if(n==0 || maxweight==0)
{
a[maxweight][n]=0;
return;
}
if(a[maxweight][n]!=-1)
return;
if(weight[n-1]>maxweight)
{
knacksnap(n-1,a,val,weight,maxweight);
a[maxweight][n]=a[maxweight][n-1];
}
else
{
knacksnap(n-1,a,val,weight,maxweight-weight[n-1]);
knacksnap(n-1,a,val,weight,maxweight);
a[maxweight][n]=max(val[n-1]+a[maxweight-weight[n-1]][n-1],a[maxweight][n-1]);
}
}
int main()
{
int n;
scanf("%d",&n);
int val[n],weight[n];
int i;
for(i=0;i<n;i++)
scanf("%d",&val[i]);
for(i=0;i<n;i++)
scanf("%d",&weight[i]);
int maxweight;
scanf("%d",&maxweight);
int a[maxweight+1][n+1];
int j;
for(i=0;i<maxweight+1;i++)
{
for(j=0;j<n+1;j++)
{
a[i][j]=-1;
}
}
knacksnap(n,a,val,weight,maxweight);
printf("\n");
printf("%d",a[maxweight][n]);
}
It not taking updated values by the knacksnap function. for example the inner knacksnap funtions are not generating correct values. eventhough their values are updated its not taking them. can someone please help

Why does the program shows memory limit exceeded in test 6 and runtime error in test 8,9,10 when i use local array variable?

Its a easy sorting problem.The problem link is https://www.hackerearth.com/practice/algorithms/sorting/quick-sort/practice-problems/algorithm/kings-race-8/
When i use global array variable the program get accepted.But when i use local array variable memory limit exceeded in case 6 and runtime error in cases 8,9,10.Why this is happened?
My code with local array variable:
#include<stdio.h>
void Quick_Sort(int a[][2],int Start,int End)
{
if(Start<End)
{
int Piv_pos=Partition(a,Start,End);
Quick_Sort(a,Start,Piv_pos-1);
Quick_Sort(a,Piv_pos+1,End);
}
}
int Partition(int a[][2],int Start,int End)
{
int i=Start+1,j,temp;
int Pivot=a[Start][0];
for(j=Start+1;j<=End;j++)
{
if(a[j][0]<Pivot)
{
temp=a[j][0];
a[j][0]=a[i][0];
a[i][0]=temp;
temp=a[j][1];
a[j][1]=a[i][1];
a[i][1]=temp;
i++;
}
}
temp=a[Start][0];
a[Start][0]=a[i-1][0];
a[i-1][0]=temp;
temp=a[Start][1];
a[Start][1]=a[i-1][1];
a[i-1][1]=temp;
return i-1;
}
int min(int a,int b)
{
if(a<b)
return a;
else
return b;
}
int main()
{
int T,i,j,N,K,prince_ind;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&K);
int a[N][2],h[K];
for(i=0;i<N;i++)
{
scanf("%d",&a[i][0]);
a[i][1]=i;
}
Quick_Sort(a,0,N-1);
/* for(i=0;i<N;i++)
{
printf("%d ",a[i][0]);
}*/
for(i=0;i<K;i++)
{
scanf("%d",&h[i]);
}
for(i=0,j=0;i<K&&j<N;i++)
{
prince_ind=a[j][1];
while(a[j][0]<h[i]&&j<N)
{
prince_ind=min(prince_ind,a[j][1]);
j++;
}
}
while(j<N)
{
prince_ind=min(prince_ind,a[j][1]);
j++;
}
printf("%d\n",prince_ind);
}
return 0;
}
My code with global array variable:
#include<stdio.h>
int a[1000000][2],h[1000000];
void Quick_Sort(int Start,int End)
{
if(Start<End)
{
int Piv_pos=Partition(Start,End);
Quick_Sort(Start,Piv_pos-1);
Quick_Sort(Piv_pos+1,End);
}
}
int Partition(int Start,int End)
{
int i=Start+1,j,temp;
int Pivot=a[Start][0];
for(j=Start+1;j<=End;j++)
{
if(a[j][0]<Pivot)
{
temp=a[j][0];
a[j][0]=a[i][0];
a[i][0]=temp;
temp=a[j][1];
a[j][1]=a[i][1];
a[i][1]=temp;
i++;
}
}
temp=a[Start][0];
a[Start][0]=a[i-1][0];
a[i-1][0]=temp;
temp=a[Start][1];
a[Start][1]=a[i-1][1];
a[i-1][1]=temp;
return i-1;
}
int min(int a,int b)
{
if(a<b)
return a;
else
return b;
}
int main()
{
int T,i,j,N,K,prince_ind;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&K);
//int a[N][2],h[K];
for(i=0;i<N;i++)
{
scanf("%d",&a[i][0]);
a[i][1]=i;
}
Quick_Sort(0,N-1);
/* for(i=0;i<N;i++)
{
printf("%d ",a[i][0]);
}*/
for(i=0;i<K;i++)
{
scanf("%d",&h[i]);
}
for(i=0,j=0;i<K&&j<N;i++)
{
prince_ind=a[j][1];
while(a[j][0]<h[i]&&j<N)
{
prince_ind=min(prince_ind,a[j][1]);
j++;
}
}
while(j<N)
{
prince_ind=min(prince_ind,a[j][1]);
j++;
}
printf("%d\n",prince_ind);
}
return 0;
}

Can't swap top element with bottom element in matrix

I'm trying to write sliding puzzle where I'm using 3x3 matrix as board. In main function user inputs the number of tile which swaps positions with 0. Everything works except when I enter number that is located in a position above zero it does not swap positions with it. How do I correct that?
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#define empty_space 0
int m,n,i,j,z,y;
void print_matrix(int matrix[3][3])
{
for ( m=0; m<3; m++){
for (n=0; n<3; n++)
{
printf("%d\t",matrix[m][n]);
} printf("\n");
}
printf("\n");
}
void swap(int *i, int *j) {
int t = *i;
*i = *j;
*j = t;
}
void slide(int a[3][3] , int t)
{
for ( i=0; i<3; i++){
for ( j=0; j<3; j++)
{
if (a[i][j]==t)
{
if (a[i+1][j]==empty_space && i+1<=2)
{
swap(&a[i+1][j],&a[i][j]);break;
}
if (a[i-1][j]==empty_space && i-1>=0)
{
swap(&a[i][j],&a[i-1][j]);break;
}
if (a[i][j+1]==empty_space && j+1<=2)
{
swap(&a[i][j],&a[i][j+1]);break;
}
if (a[i][j-1]==empty_space && j-1>=0)
{
swap(&a[i][j],&a[i][j-1]);break;
}
}
}
}
}
int goal_test (int a[3][3],int b[3][3])
{
int flag=0;
for ( z=0; z<3; z++){
for ( y=0; y<3; y++){
if(a[z][y]==b[z][y])
flag++;
}
}
if (flag==9)
return 1;
else return 0;
}
int main()
{
static int mat[3][3]={{1,2,3},{6,0,4},{7,5,8}};
int goal[3][3]={{1,0,3},{6,5,4},{7,8,2}};
print_matrix(mat);
int x;
while(goal_test(mat,goal)==0)
{
printf("enter tile to slide:\t");
scanf("%d",&x);
slide(mat, x);
print_matrix(mat);
}
return 0;
}
Here's what happens:
Any number can swap its position as long as it's not located above zero

Function string_to_table is breaking on 3rd if c

I am trying to create program to add two matrixes. After typing input like [12 4] program crashes when function strcat starts.
I have no idea what is wrong. func.h consists of stdio.h, _mingw.h,stdlib.h and string.h
#include"func.h"
void string_to_table(double **matrix, char inpt[])/*problematic function*/
{
printf("convertion start");
int i=strlen(inpt);
printf("%i",i);
int j=1;
int k=0,l=0;
char num[128];
double converted=0;
printf("breakpoint1");
while(j<(i-1))
{
if(inpt[j]==' ')
{
printf("first if");
converted=atof(num);
num[0]='\0';
matrix[k][l]=converted;
++l;
printf("breakpoint2");
}
else if(inpt[j]==';')
{
printf("second if");
converted=atof(num);
num[0]='\0';
matrix[k][l]=converted;
++k;
l=0;
}
else
{
printf("third if");
strcat(num,inpt[j]);/*place when everything crashes*/
}
++j;
}
printf("convert0 end");
}
void add_matrix(double **matrix1, double **matrix2,int i,int j)
{
int k=0;
int l=0;
while(k<i)
{
while(l<j)
{
matrix1[k][l]+=matrix2[k][l];
++l;
}
l=0;
++k;
}
int matrixproccesing(int *i,int *j, char m[])/*sprawdzanie poprawnosci wejscia*/
{
printf("macro start");
int columnnum=0,rownum=0,x=0,piv=0,check=0;
int textsize=strlen(m);
printf("%i",i);
printf("loop start");
printf("%i",textsize);
while(x<(textsize-1))
{
printf("%i",x);
printf("\n");
if(x==0)/*czy poczatek to [*/
{
if(m[x]!='[')
return 0;
}
else if(x==(textsize-2))/*czy koniec to]*/
{
printf("kohec");
if(m[x]==']')
break;
return 0;
}
else if((m[x]>47&&m[x]<58)||(m[x]==' ')||(m[x]=='.')||(m[x]==';')||(m[x]=='-'))/*czy liczba*/
{
if(m[x]==';')/*czy ilosc liczb w rzedzie taka sama*/
{
if(check==0)
{
check=columnnum;
}
else if(check!=columnnum)
{
return 0;
}
printf("colnum");
columnnum=0;
rownum++;
}
else if(m[x]==' ')/*czy nowa liczba/kolumna */
{
columnnum++;
}
}
++x;
}
*i=(check+1);
*j=(columnnum+1);
printf("macro end");
return 1;
}
int is_same_size(int a, int b,int c ,int d)/*test rozmiaru*/
{
if((a==c)&(b==d))
return 1;
return 0;
}
void print_da_matrix(double **matrix, int i, int j)
{
int k=0,l=0;
printf("[ ");
while(k<i)
{
while(l<j)
{
printf("%f",matrix[k][l]);
printf(" ");
}
printf(";");
l=0;
if(k<(i-1))
++k;
}
printf("]");
}
void release_the_memory(double **matrix, int i)
{
int k=0;
while(k<i)
{
free(matrix[k]);
++k;
}
free(matrix);
matrix=NULL;
}
}
int main()
{
int i=0,j=0,m1=0,m2=0,tabcr=0;
char matrix[512];
fgets(&matrix,511,stdin);
double **matrix1;
double **matrix2;
if(!matrixproccesing(&i,&j,matrix))
{
printf("zle wejscie");
return 0;
}
matrix1=(double**)malloc(i*sizeof(double *));
while(tabcr<j)
{
matrix1[tabcr]=(double*)malloc(j*sizeof(double));
++tabcr;
}
string_to_table(matrix1,matrix);
printf("\n");
printf("podaj druga macierz");
fgets(&matrix,511,stdin);
if(!matrixproccesing(&m1,&m2,matrix))
{
printf("zle wejscie");
return 0;
}
tabcr=0;
if(!is_same_size(i,j,m1,m2))
{
printf("matrixes have different size.");
return 0;
}
matrix2=(double**)malloc(i*sizeof(double *));
while(tabcr<j)
{
matrix2[tabcr]=(double*)malloc(j*sizeof(double));
++tabcr;
}
string_to_table(matrix2,matrix);
add_matrix(matrix1,matrix2,i,j);
/* print_da_matrix(matrix1,i,j);
release_the_memory(matrix1,i);
release_the_memory(matrix2,i);*/
return 0;
}

Resources