Gauss-Jordan Elimination in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So, I have some class work that I cannot solve. I could get the code to work partially but now it is just useless. It either freezes (doesn't complete running) or it will give me several inf in the first row.
#include <stdio.h>
#include <math.h>
int main()
{
double a[10][11]={
{3.55618, 5.87317, 7.84934, 5.6951, 3.84642, 9.15038, -1.68539, 5.03067, 7.63384, -1.75626, -1.92193},
{-4.82893, 8.38177, -0.301221, 5.10182, -4.1169,-6.09145, -3.95675, -2.33365, 1.3969, 6.54555, -2.35262},
{-7.64196, 5.66605, 3.20481, 1.55619, -1.19814, 9.79288, 5.35547, 5.86109, 4.95544, -9.35749, 2.27709},
{-2.95914, -9.16958, 7.3216, 2.39876, -8.1302, -7.55135, -2.37718, 7.29694, 5.9867, 8.5401, -2.67493},
{-8.42043, -0.369407, -5.4102, -8.00545, 9.22153, 3.96454, 5.38499, 0.438365, 0.419677, 4.17166, 1.84756},
{6.02952, 4.57728, 5.46424, 3.52915, -1.01135, -3.74686, 8.14264, -8.86961, -2.88114, 1.29821, 4.154126},
{0.519819, -6.16655, 1.13216, 2.75811, -1.05975, 4.20286, -3.45764, 0.763558, -0.281287, -9.76168, -.93387},
{5.15737, -9.67481, 9.29904, -3.93334, 9.12785, -4.25208, -6.1652, 2.5375, 0.139195, 2.00106, -1.28356},
{-4.30784, 1.40711, -6.97966, -9.29715, 5.17234, 2.42634, 1.88818, -2.05526, -3.7679, 3.3708, -3.46841},
{-4.65418, 7.18118, 6.51338, 3.13249, 0.188456, -16.85599, 7.21435, -2.93417, 1.06061, 1.10807, -2.61529}};
int i, j, k, l;
double b[10][11];
i=0;
while(i<10)
{
j=0;
l=i;
while(l<10)
{
j=0;
l++;
while(j<11)
{
This code below works fine. When used on its own, it will turn all the diagonal values into 1.
b[i][j]=a[i][j]/a[i][i];
This code used below to work partially, setting the first column equal to 0, but now it is useless. I tried to manipulate it into getting rid of all values by having that 0 be a k, with k++ within the while code, but it would return either a segmentation code if I placed it by the i++; or a bus error is placed in front of the j=0;, and it would just freeze the program if I placed the i in the 0. Now it is useless that I restored it to default
b[l][j]=a[l][j]-b[i][j]*a[l][0];
j++;
}
}
i++;
}
j=0;
i=0;
while(i<10)
{
while(j<11)
{
printf("%lf\t", b[i][j]);
j++;
}
printf("\n");
i++;
j=0;
}
return 0;
}
How do I go about solving all these issues within my C program?

Not 100% sure what your code is up to, but I see at least 1 place where I believe that you are reading off the end of your arrays:
while(l<10)
{
j=0;
l++;
...
b[l][j]=a[l][j]-b[i][j]*a[l][0];
Because you are incrementing after you check for max size, you have 1 iteration where you are probably reading passed the max size of the array.
To check, put some prints on your indexes in your code where you do your assignments or assert them or something and I think you will find the source of your woes.
Also, PLEASE use constants for your sizes instead of the magic numbers all over the place. You will thank me later when trying to do a calculation of a matrix of a different size.

Related

How do I resolve this int overflow? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
int frequency(string note)
{
int i;
float f;
int n=0;
float octave= note[strlen(note)-1];
if(strlen(note)==3)
{
if(note[1]=='#')
{
n+=1;
}
else if(note[1]=='b')
{
n-=1;
}
}
if(note[0]=='B')
{
n+=2;
}
else if(note[0]=='C')
{
n-=9;
}
else if(note[0]=='D')
{
n-=7;
}
else if(note[0]=='E')
{
n-=5;
}
else if(note[0]=='F')
{
n-=4;
}
else if(note[0]=='G')
{
n-=2;
}
n+=(octave-4.0)*12.0;
float p= n/12.0;
f=(int)(round(pow(2.0,p)*440.0));
return f;
}
So basically whenever I run this code I get an error stating "runtime error: value 7.3641e+16 is outside the range of representable values of type 'int'"
Then the value returned is just-2147483648. I've looked it up online and haven't found an answer that helps me with my code. Also this was made in the cs50 IDE so there are a bunch of commands and things that are imported. My program compiles properly and it can run so how do I fix this?
Frequencies of notes of the chromatic scale are not integers in the first place.
If you are passed a two character string like Cb, you get a stupidly huge octive with a frequency way too high.

Vigenere cipher in cs50 Segfau [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am not experienced coder.Please dont judge for bad styling.I've run into an issue with the vingenere cipher
It keeps giving me segfau
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>**
int main(int argc,string argv[])
{
while (argc!=2)
{
printf("Incorrect input\n");
return 1;
}
printf("plaintext:");
string plaintext=get_string();
string num=argv[1];
int keylength=strlen(num);
for (int j=0, n=strlen(plaintext); j<n; j++)
{
char letter=plaintext[j];
if (isalpha(letter))
{
This is the reason of Segmantation Fault error.
If i don't check if num is upper or lower case,
code runs normally.
if (isupper(letter))
{
if (isupper(num))
{
printf ("%c",((((letter-65)+(num[j%keylength]-65))%26)+65));
}
else
{
printf ("%c",((((letter-65)+(num[j%keylength]-97))%26)+65));
}
}
else
{
if (isupper(num))
{
printf ("%c",((((letter-97)+(num[j%keylength]-65))%26)+97));
}
else
{
printf ("%c",((((letter-97)+(num[j%keylength]-97))%26)+97));
}
}
}
else
{
printf ("%c",letter);
}
}
printf("\n");
return 0;
}
Most likely, you meant
if (isupper(num[j % keylength))
Passing a string (really a char *) to isupper() is an undefined operation, and may produce weird effects depending on how isupper() is implemented. The GNU implementation ---
#define __ctype_lookup(__c) ((__ctype_ptr__+sizeof(""[__c]))[(int)(__c)])
#define isupper(__c) ((__ctype_lookup(__c)&(_U|_L))==_U)
--- uses a lookup table with all sorts of fun pointer math and casting under the hood, so it likely allows a char * to be passed without the compiler complaining, but it's definitely not going to produce good results. Change your if statement, and it should work better.

How can I change my iterative code to a recursive one? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
int findnumb(int max)
{
int left,right,total,desk;
for(total=2; total<=max; total++)
{
for(desk=1; desk<total; desk++)
{
left=desk*(desk-1)/2;
right=(total*(total+1)/2)-(desk*(desk+1)/2);
if(left==right)
{
printf("Desk number %d, number of participants %d\n", desk, total);
break;
}
}
}
}
How can I turn this into a recursive function?
It works well in this form, but when I try to change it to a recursive function it compiles, but doesn't work properly, what should I do?
Edit:
It is for a riddle like this:
Suppose that there exists a meeting and we do not know how many people attend to it.
However, we see a man quitting from the meeting. If we ask the man how many people
exist at the meeting he just replies “I do not know”. Nonetheless he says “I was sitting on
a chair numbered x and summation of the numbers below and above me equals. In other
words, if the number of the chair is x, then 1,2,3….x-1 = x+1 x+2 …...t-1,t (total
participant count). Besides, we do not know the value of t and the chair number x.
Total participant 8, and the chair number 6 is an example configuration. Because
1+2+3+4+5 = 7+8 = 15. Your task is to find similar configurations by one by one try-out.
And It wants the solution to implement a recursive function
Second Edit:
Now I have produced a code that finds the numbers and crashes right after that why is it happening?
Here is the screenshot of the code and the crash http://imgur.com/a/UgZgC
The variables that need to change in each iteration need to be argumants and you need to be true to the functional approach so instead of printing you should return the result:
int findnumb_aux(int max, int total, int desk)
{
if( total > max ) {
return 0; // need to return something when no solution exist
} elseif( desk < total ) {
int left=desk*(desk-1)/2;
int right=(total*(total+1)/2)-(desk*(desk+1)/2);
if(left==right) {
return desk<<8+total; // there are better ways to return two numbers. you figure it out
} else {
return findnum_aux(max, total, desk+1);
}
} else {
return findnum_aux(max,total+1, 1);
}
}
int findnum(int max)
{
return findnum_aux(max, 2, 1);
}
Fun fact: This code is still iterative since it does not grow the stack if your C compiler has tail call optimization.

I am getting runtime error (SIGSEGV) in a c program [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Why I am getting runtime error (SIGSEGV) on the following code:
#include<stdio.h>
#include<string.h>
int main()
{
int t_line,count[10000],i;
scanf("%d",&t_line);
for(i=1;i<=t_line;i++)
{
fflush(stdin);
gets(t);
count[i]=(int)t[0]+(int)t[1]+(int)t[2];
}
for(i=1;i<=t_line;i++)
printf("%d\n",count[i]);
return 0;
}
I have also tried to solve this problem by initialized all the elements of array.
I am wondering how the code compiled, without declaration of the variable t. But, still the only missing elemnt was: char t[your choice of size];. Apart from that
#include<stdio.h>
//#include<string.h> No need of this header,a s you are not using any string functions
int main()
{
int t_line,count[10000],i;
char t[64];//you need to declare the variable before using it
scanf("%d",&t_line);
//Its safer if you check this
if(t_line >= 10000)//if you use 0 and < t_line in for loop below then change the condition to: if(t_line > 10000)
{
printf("ERROR: Limit exceeded. Not enough memory.\n");
return 1;//or you could use exit(1); and #include <stdlib.h>
}
for(i=1;i<=t_line;i++)//suggested: for(i=0;i<t_line;i++)
{
//fflush(stdin);
//gets(t);
char *rc = fgets(t, sizeof(t), stdin);
if(rc != NULL)
{ t[strlen(t) - 1] = '\0';\\because fgets gets the \n into the string too. This line makes fgets similar to gets, improving safety from overflow.
}
else
{
// handle fgets failed error
}
count[i]=(int)t[0]+(int)t[1]+(int)t[2];
}
for(i=1;i<=t_line;i++)//suggested: for(i=0;i<t_line;i++)
printf("%d\n",count[i]);
return 0;
}
Find the solution and suggested changes inline as code comments.
In C, its better to use indexes starting from 0, unless there is a specific requirement to use other values.

Deciding the base condition in backtracking recursive algorithm

I was solving the N Queen problem where we need to place 4 queens on a 4 X 4 chess board such that no two queens can attack each other. I tried this earlier but my approach did not involve backtracking, so I was trying again. The code snippets are
int size=4,i,j;
int arr[4][4];
int lastjindex[4]; // to store the last location which we may need to backtrack
void placeQueen(int i,int j)
{
int availableornot=0;
for(j=0;j<size;j++)
{
if(isAvailable(i,j)==1)
{
availableornot=1;
break;
}
}
if(availableornot==1)
{
arr[i][j]=1;
lastjindex[i]=j;
if((i+1)!=size)
{
placeQueen(i+1,0);
}
}
else
{
// no column was availabe so we backtrack
arr[i-1][lastjindex[i-1]]=0;
placeQueen(i-1,lastjindex[i-1]+1);
}
}
The isAvailable() method returns 1 if arr[i][j] is not under attack, else it returns 0.
int isAvailable(int i,int j)
{
int m,n,flag=0;
for(m=0;m<i;m++)
{
for(n=0;n<size;n++)
{
int k=abs(i-m);
int l=abs(j-n);
if(arr[m][j]==0 || arr[k][l]==0)
{
flag=1;
break;
// means that spot is available
}
}
}
return flag;
}
I call the above method from main as
placeQueen(0,0);
My program compiles successfully but it prints all zeroes.
Is there any problem with my recursion? Please help me correct my code as I am trying to learn how to implement backtracking algorithms!
Also I am not able to decide the base condition to end recursion. How do I choose it here?
There's no printing in the code you posted. If you print after you have backtracked, you will be back to the initial condition of no queens on the board. Print after you have placed N queens, which is also the end condition for recursion. If you only want to print one solution, exit after printing, or set a flag that tells the caller that you're done so you pop all the way out. If you print all solutions, that will include reflections and rotations. You can eliminate one axis of reflection by only placing queens within size/2 in the first level.
Also, there are some clear logic errors in you code, such as
arr[m][j]==0 || arr[k][l]==0
A queen can only be placed if it isn't attacked on the file and it isn't attacked along a diagonal. Use a debugger or add printfs to your code to trace where it is trying to place queens -- that will help you figure out what it is doing wrong.
And aside from being wrong, your isAvailable is very inefficient. You want to know if the [i,j] square is attacked along the file or a diagonal. For that you should have a single loop over the rows of the previous queens for (m = 0; m < i; m++), but you only need three tests, not a loop, to check the file and the diagonals. As soon as you find any previous queen on a file or diagonal, you're done, and the square isn't available -- return false. (And ignore people who tell you that a function should only have one return -- they are wrong, and there are lengthly discussions here at SO and even scientific studies of error rates in code that bear this out.) Only if no previous queen is found is the square available.
Your placeQueen is also wrong. For each available square on a row, you need to place a queen and then recurse, but you're just finding the first available square. And backtracking is achieved simply by removing the queen you placed and then returning ... the previous level of placeQueen will try the next available spot.
Again, trace the code to see what it's doing. And, even more importantly, think through the logic of what is needed. Write your algorithm in words, convince yourself that it will solve the problem, then write the code to carry out the algorithm.
#include <stdio.h>
#define SIZE 4
int size=SIZE;
int arr[SIZE][SIZE] = { 0 };
void placeQueen(int col){
int r,c;
if(col == size){//all queen put!
//print out
for(r = 0;r<size;++r){
for(c = 0;c<size;++c)
printf("%d", arr[c][r]);
printf("\n");
}
printf("\n");
return ;
}
for(r=0;r<size;++r){
if(isAvailable(col, r)==1){
arr[col][r]=1;
placeQueen(col+1);
arr[col][r]=0;//reset
}
}
}
int isAvailable(int col,int row){
int c;
for(c=0;c<col;++c){
int d = col - c;
if(arr[c][row]==1)
return 0;//queen already same row
if(row+d < size && arr[c][row+d]==1 || row-d >= 0 && arr[c][row-d]==1)
return 0;//queen already same slanting position
}
return 1;
}
int main(){
placeQueen(0);
return 0;
}

Resources