Gauss-seidel method algorithm code giving inf numbers in solution - c

I'm not sure why I'm getting inf values when plugging in a 3 equation answer, another set of eyes on the equation loop would be useful, when I use a single equation the number of iterations is correct but when it's more than that the numbers multiply to inf.
Inputs for the code I used
Enter the Total Number of Equations: 3
Enter Allowed Error: 0.5
Enter the Co-Efficients
Matrix[1][1] = 1
Matrix[1][2] = 2
Matrix[1][3] = 3
Matrix[1][4] = 4
Matrix[2][1] = 2
Matrix[2][2] = 3
Matrix[2][3] = 4
Matrix[2][4] = 5
Matrix[3][1] = 3
Matrix[3][2] = 4
Matrix[3][3] = 5
Matrix[3][4] = 6
#include<stdio.h>
#include<math.h>
int main()
{
int count, t, limit;
float temp, error, a, sum = 0;
float matrix[10][10], y[10], allowed_error;
printf("\nEnter the Total Number of Equations:\t");
scanf("%d", &limit);
printf("Enter Allowed Error:\t");
scanf("%f", &allowed_error);
printf("\nEnter the Co-Efficients\n");
for(count = 1; count <= limit; count++)
{
for(t = 1; t <= limit + 1; t++)
{
printf("Matrix[%d][%d] = ", count, t);
scanf("%f", &matrix[count][t]);
}
}
for(count = 1; count <= limit; count++)
{
y[count] = 0;
}
do
{
a = 0;
for(count = 1; count <= limit; count++)
{
sum = 0;
for(t = 1; t <= limit; t++)
{
if(t != count)
{
sum = sum + matrix[count][t] * y[t];
}
}
temp = (matrix[count][limit + 1] - sum) / matrix[count][count];
error = fabs(y[count] - temp);
if(error > a)
{
a = error;
}
y[count] = temp;
printf("\nY[%d]=\t%f", count, y[count]);
}
printf("\n");
}
while(a >= allowed_error);
printf("\n\nSolution\n\n");
for(count = 1; count <= limit; count++)
{
printf("\nY[%d]:\t%f", count, y[count]);
}
return 0;
}

Your code is correct. The issue is that Gauss-Seidel method does not always converge. The convergence criteria is that the matrix A must be either:
symmetric positive-definite
strictly or irreducibly diagonally dominant
The input matrix you used is neither symmetric, nor diagonally-dominant. Hence, the method fails to converge to a solution.

Related

I want to print a series of Armstrong numbers which lie between m and n. Here m and n are the two inputs given by the user

I am trying to print the series but whenever I set the range (input given by me) above 407. I only get the output till 407. However, when I set the range below 407 it gives me the result according to the input I have given. Can anybody tell me what I'm doing wrong?
I used an online compiler (www.onlinegdb.com) to write my code.
Here is the code.
#include<stdio.h>
#include<stdlib.h>
int
main ()
{
int m, n;
printf
("Enter two numbers to find the Armstrong numbers that lie between them.\n");
scanf ("%d%d", &m, &n);
system("clear");
if(m>n)
{
m = m + n;
n = m - n;
m = m - n;
}
for (; m < n; m++)
{
int i = m + 1, r, s = 0, t;
t = i;
while (i > 0)
{
r = i % 10;
s = s + (r * r * r);
i = i / 10;
}
if (t == s)
printf ("%d ", t);
}
return 0;
}
enter image description here
enter image description here
Try this code!!!
#include <math.h>
#include <stdio.h>
int main() {
int low, high, number, originalNumber, rem, count = 0;
double result = 0.0;
printf("Enter two numbers(intervals): ");
scanf("%d %d", &low, &high);
printf("Armstrong numbers between %d and %d are: ", low, high);
// swap numbers if high < low
if (high < low) {
high += low;
low = high - low;
high -= low;
}
// iterate number from (low + 1) to (high - 1)
// In each iteration, check if number is Armstrong
for (number = low + 1; number < high; ++number) {
originalNumber = number;
// number of digits calculation
while (originalNumber != 0) {
originalNumber /= 10;
++count;
}
originalNumber = number;
// result contains sum of nth power of individual digits
while (originalNumber != 0) {
rem = originalNumber % 10;
result += pow(rem, count);
originalNumber /= 10;
}
// check if number is equal to the sum of nth power of individual digits
if ((int)result == number) {
printf("%d ", number);
}
// resetting the values
count = 0;
result = 0;
}
return 0;
}
Try this code :
#include <stdio.h>
#include <math.h>
int main()
{
int start, end, i, temp1, temp2, remainder, n = 0, result = 0;
printf(“Enter start value and end value : “);
scanf(“%d %d”, &start, &end);
printf(“\nArmstrong numbers between %d an %d are: “, start, end);
for(i = start + 1; i < end; ++i)
{
temp2 = i;
temp1 = i;
while (temp1 != 0)
{
temp1 /= 10;
++n;
}
while (temp2 != 0)
{
remainder = temp2 % 10;
result += pow(remainder, n);
temp2 /= 10;
}
if (result == i) {
printf(“%d “, i);
}
n = 0;
result = 0;
}
printf(“\n”);
return 0;
}

ReArrange a number with ascending digits

I have to solve a problem where one of the important tasks is to reorder the digits of the input in ascending order and we are not allowed to use arrays and lists. I have no problem with that and my code works, but only if we do not consider leading 0, which we should in this problem. The only way I see how to do is to check digit by digit and then add then ordered by multiplying the number by 10 and adding the next digit. (1*10 = 10, 10+3= 13, we got 1 and 3 ordered) However, if we have a 0 in our number this method will not work because if I want to make 0123 with the * 10 method, I won't be able to have the 0 as the first digit never. Does anyone know how to solve this? My code is below:
int ascendingNumbers (int n) { //This function sorts the number on an ascending order
int number = n;
int sortedN = 0;
for (int i = 0; i <= 9; i++) {
int toSortNumber = number;
for (int x = 0; x <= 4; x++) {
int digit = toSortNumber % 10;
if (digit == i) {
if (digit == 0) {
sortedN==10;
}
sortedN *= 10;
sortedN += digit;
}
toSortNumber /= 10;
}
}
return sortedN;
}
Normally I don't do homework problems, but for especially awful ones I'll make an exception.
(Also I'm making an exception to my general rule not to have anything to do with these absurd "desert island" constraints, where you're stranded after a shipwreck and your C compiler's array functionality got damaged in the storm, or something.)
I assume you're allowed to call functions. In that case:
#include <stdio.h>
/* count the number of digits 'd' in 'n'. */
int countdigits(int n, int d)
{
int ret = 0;
/* do/while so consider "0" as "0", not nothing */
do {
if(n % 10 == d) ret++;
n /= 10;
} while(n > 0);
return ret;
}
int main()
{
int i, n;
printf("enter your number:\n");
scanf("%d", &n);
printf("digits: ");
for(i = 0; i < 10; i++) {
int n2 = countdigits(n, i);
int j;
for(j = 0; j < n2; j++) putchar('0' + i);
}
printf("\n");
}
This solution does not involve a function int ascendingNumbers() as you asked about. If you want to handle leading zeroes, as explained in the comments, you can't do it with a function that returns an int.
Your zero problem is solved, check it...
class Main {
public static void main(String[] args) {
int number = 24035217;
int n = number, count = 0;
int sortedN = 0;
while (n != 0) {
n = n / 10;
++count;
}
for (int i = 9; i >= 0; i--) {
int toSortNumber = number;
for (int x = 1; x <= count; x++) {
int digit = toSortNumber % 10;
// printf("\nBefore i = %d, x = %d, toSortNumber = %d, sortedN = %d, digit = %d",i,x,toSortNumber,sortedN,digit);
if (digit == i) {
sortedN *= 10;
sortedN += digit;
}
// printf("\nAfter i = %d, x = %d, toSortNumber = %d, sortedN = %d, digit = %d",i,x,toSortNumber,sortedN,digit);
toSortNumber /= 10;
}
}
System.out.print(sortedN);
}
}

How optimize below code to determine the total number of prime numbers below 1,000,000,000 have the sum of their digits equal to 14 in C?

/Write a program to determine the total number of prime numbers below 1000,000,000 have the sum of their digits equal to 14? Make sure the execution time is few seconds./
#include<stdio.h>
#include<math.h>
int main() {
int i, j, count = 0, temp = 0, n, ans = 0, tot = 0;
for (i = 1; i <= 1000000000; i++) {
for (j = 2; j <= i / 2; j++) {
if (i % j == 0) {
count++;
}
}
if (count == 0) {
n = i;
while (n != 0) {
temp = n % 10;
n = n / 10;
ans = ans + temp;
}
if (ans == 14) {
tot++;
printf("%d,", i);
}
ans = 0;
temp = 0;
}
count = 0;
}
// printf("%d:\n",tot);
return 0;
}
Two simply improvements (amongst other):
1: Rather than iterate to i/2, iterate to the square root of i - that is j*j <= i.** This is a huge speed-up.
2: Quit loop once a factor found.
// for(j=2;j<=i/2;j++) {
// if(i%j==0) {
// count++;
// }
//}
for(j=2;j<=i/j;j++) { // _much_ lower limit
if(i%j==0) {
count++;
break; // No need to find more factors: `i` is not a prime.
}
}
Functionality: Inside if(count==0), I'd expect ans == 0 before while(n!=0).
** Use j<=i/j to prevent overflow. A good compiler will see a nearby i%j and often perform both i/j, i%j for the time cost of one.
The digit-sum function could also use a early return like:
int dsum14(int n) {
int sum = 0;
for (; n; n /= 10)
if ((sum += n % 10) > 14)
return 0;
return sum == 14 ? 1 : 0;
}
But how to combine the (efficient) prime search and this sum condition?
int n, cnt = 0;
for (n = 3; n < 1000*1000*1000; n += 2)
if (n%3 && n%5 && dsum14(n) && n%7 && n%11 && n%13)
cnt++;
This gives 77469 in 1.5 seconds. With dsum() at either end of the logical chain it is almost double.
The && n%7 && n%11 && n%13 part would be replaced by a function using a list of primes up to about 32000 (square root of max).
...or you can optimize it to 0.1 seconds, by tweaking the digsum function.
There are "only" 575 three-digit numbers 000-999 with sum 14 or less. So I prepare them and combine three of them to get a 9-digit number. Generating them instead of filtering them.
The tail looks like:
920000021
920000201
920001011
920010011
920100011
920100101
920101001
921001001
931000001
total count: 22588
real 0m0.098s
user 0m0.100s
sys 0m0.002s
And the start:
59
149
167
239
257
293
347
383
419
Not 100% sure if it's correct, but the total count also seems reasonable.
It all relies on the given max of 1000 Mio. digsum_prime() uses it to build the candidate number from three (almost) equal parts.
Code:
#include <stdio.h>
#include <stdlib.h>
int parr[5000] = {3};
struct {
int tri, sum;
} ts[999];
void primarr(void) {
int maxn = 32000;
int i = 1;
for (int n = 5; n < maxn; n += 2)
for (int div = 3;; div += 2) {
if (!(n % div))
break;
if (div*div > n) {
parr[i++] = n;
break;
}
}
}
int isprime(int n) {
for(int i = 0;; i++) {
if (!(n % parr[i]))
return 0;
if (parr[i]*parr[i] > n)
return 1;
}
}
int dsum(int n) {
int sum = 0;
for (; n; n /= 10)
sum += n % 10;
return sum;
}
int tsarr(void) {
int i = 0;
for (int n = 0; n < 1000; n++) {
int digsum = dsum(n);
if (digsum <= 14) {
ts[i].tri = n;
ts[i].sum = digsum;
i++;
}
}
return i;
}
int digsum_prime() {
int cnt = 0;
int tslen = tsarr();
printf("tslen: %d\n", tslen);
int high, mid, low;
int sum, num;
for (high = 0; high < tslen; high++) {
if(ts[high].sum > 13)
continue;
for (mid = 0; mid < tslen; mid++) {
if(ts[mid].sum + ts[high].sum > 13)
continue;
sum = ts[mid].sum + ts[high].sum;
for (low = 0; low < tslen; low++)
if (ts[low].tri % 2)
if(ts[low].sum + sum == 14) {
num = ts[high].tri * 1000*1000
+ ts[mid] .tri * 1000
+ ts[low] .tri;
if (isprime(num)) {
cnt++;
printf("%d\n", num);
}
}
}
}
return cnt;
}
int main(void) {
primarr();
printf("total count: %d\n", digsum_prime());
}
Changing 13-13-14 to 3-3-4 (but same preparation part) gives an overview - in 0.005 s!
tslen: 575
13
31
103
211
1021
1201
2011
3001
10111
20011
20101
21001
100003
102001
1000003
1011001
1020001
1100101
2100001
10010101
10100011
20001001
30000001
101001001
200001001
total count: 25
real 0m0.005s
user 0m0.005s
sys 0m0.000s
Make sure the execution time is few seconds.
oops
But the limits of OP are well chosen: a naive approach takes several seconds.

multiplying number from 1 to N while adding 2 every time

I have to write a C program that multiplies numbers from 1 to N.
N is scanned. Before multiplication, I have to increase each number by 2.
For example: N = 3 => (1+2)(2+2)(3+2) = 60
I have to only use while loop and print and scan function.
Example program:
Enter the value of N: 4
The result of multiplication: 360
This is my code and I am not sure what is wrong with this. Please help.
#include <stdio.h>
int N;
int count=1, ii, result;
printf("Enter the value of N:");
scanf("%d", &N);
while (count<=N)
{
count ii = count + 2;
ii = ii * ii ; //three
count++;
}
result = ii;
printf("The result of multiplication: %d", result);
return 0;
}
If you're looking for that series as a sum:
const int N = 3;
int c = 1;
for (int i = 1; i <= N; ++i) {
c *= (i + 2);
}
Or in a more C-esque form:
const int N = 3;
int c = 1;
for (int i = 0; i < N; ++i) {
c *= (i + 1 + 2);
}
int main()
{
int N;
int count=1, ii = 1, result;
printf("Enter the value of N:");
scanf("%d", &N);
while (count<=N)
{
ii = ii * ( count + 2 };
count++;
}
result = ii;
printf("The result of multiplication: %d", result);
return 0;
}

How to find the highest and the lowest averages using 2D arrays in c programming?

there's a mistake in my code but i can't find where. it must calculate the averages after reading inputs.
it reads all the code and gets all the inputs but when it comes to calculating the average it does nothing. help please
#include <stdlib.h>
#include <stdio.h>
int main() {
int students, modules, m, n, first_student, last_student, l = 0;
float student[100][20], high = 0, low = 20, average[students], average_mark[students];
printf("Please enter the number of students:\n");
scanf("%d", &students);
printf("Please enter the number of modules:\n");
scanf("%d", &modules);
for (m = 0; m < students; ++m) {
for (n = 0; n < modules; n++) {
printf("Please enter the mark of module %d for student number %d,\n", n + 1, m + 1);
scanf("%f", &student[m][n]);
}
}
for (m = 0; m < students; ++m) {
average[m] = 0;
}
for (n = 0; n < modules; n++) {
average[m] += student[m][n];
average_mark[m] = average[m] / modules;
}
printf("student average\n");
for (m = 0; m < students; ++m) {
printf("%d %f\n", m + 1, average_mark[m]);
}
for (m = 0; m < students; ++m) {
if (average_mark[m] < low) {
average_mark[m] = low;
}
else
if (average_mark[m] == low) {
last_student = m + 1;
}
if (average_mark[m] > high) {
average_mark[m] = high;
}
else
if (average_mark[m] == high) {
first_student = m + 1;
}
}
printf("The student who had the highest mark is %d : %f\n", first_student, high);
printf("The student who had the lowest mark is %d : %f\n", last_student, low);
for (m = 0; m < students; ++m) {
if (average_mark[m] == 10 || average_mark[m] > 10) {
l++;
}
}
printf("the number of students having a mark that equals or exceeds the average is %d\n", l);
return 0;
}
There are some other problems in the code but as a start, you may take a peek below.
edit: The next (2nd) problem noted & corrected. I'm leaving you to find & correct the last (3rd) problem.
// either these values need to be predefined
// or you'll need to dynamically allocate
// arrays using malloc
int MAX_STUDENTS = 100;
int MAX_MODULES = 20;
int main() {
int students, modules, m, n, first_student, last_student, l = 0;
float student[MAX_STUDENTS][MAX_MODULES], high = 0, low = 20, average[MAX_STUDENTS], average_mark[MAX_MODULES];
...
...
...
// the 2nd & 3rd for loops needs to be nested as below
for (m = 0; m < students; ++m) { // this was 2nd
average[m] = 0;
for (n = 0; n < modules; n++) { // this was 3rd
average[m] += student[m][n];
}
// you need to move this line out of 3rd loop
average_mark[m] = average[m] / modules;
}
...
...
...
// this is how you find the lowest & highest ranking students
for (m = 0; m < students; ++m) {
if (average_mark[m] < low) {
low = average_mark[m];
last_student = m;
}
if (average_mark[m] > high) {
high = average_mark[m];
first_student = m;
}
}
printf("The student who had the highest mark is %d : %f\n", first_student + 1, high);
printf("The student who had the lowest mark is %d : %f\n", last_student + 1, low);
...
...
...
}

Resources