Sum of prime factors - c

I am trying to show the sum of the prime factors of a given number and
I'm having difficulties displaying the prime factors in my output.
Sample Output:
Input number: 6
Factors are: 1 2 3
Sum of its factor: 1 +2 +3 =6
I am able to show the sum but I want to show the 1+2+3=6 like in the sample above where the factors are 1 2 3.
Can you help me correct my syntax to achieve this? Thanks in advance.
Here's my code:
#include <stdio.h>
int main() {
int i, j, num, isPrime, sum;
printf("Input number: ");
scanf("%d", &num);
printf("Factors are: ", num);
for (i = 1; i <= num; i++) {
if (num % i == 0) {
isPrime = 1;
for (j = 2; j <= i / 2; j++) {
if (i % j == 0) {
isPrime = 0;
break;
}
}
if (isPrime == 1) {
printf("%d ", i);
sum += i;
}
}
}
printf("\nSum of its factor : %d", sum);
return 0;
}

Your code actually has undefined behavior because sum is not initialized to 0. It produces the correct sum only by chance.
You can store the factors in an array, or even construct the expression as you go with sprintf. The maximum length of the expression is not very large as there can be at most 9 different prime factors (29!! > 232)
Here is a modified version:
#include <stdio.h>
int main() {
char expr[9 * 11 + 1];
int i, j, pos, num, isPrime, sum;
printf("Input number: ");
if (scanf("%d", &num) != 1)
return 1;
printf("Factors are: 1"); // always include 1
pos = 0;
expr[pos] = '\0';
sum = 1;
for (i = 2; i <= num; i++) {
if (num % i == 0) {
isPrime = 1;
for (j = 2; j * j <= i; j++) {
if (i % j == 0) {
isPrime = 0;
break;
}
}
if (isPrime == 1) {
pos += sprintf(expr + pos, "+%d", i);
printf(" %d", i);
sum += i;
}
}
}
printf("\nSum of its factors: 1%s = %d\n", expr, sum);
return 0;
}
Output:
Input number: 6
Factors are: 1 2 3
Sum of its factors: 1+2+3 = 6
Here is a more robust and much faster version that does not have undefined behavior for very large values of num:
#include <stdio.h>
int main() {
char expr[9 * 11 + 1];
int i, pos, num;
unsigned sum;
printf("Input number: ");
if (scanf("%i", &num) != 1)
return 1;
printf("Factors are: 1"); // always include 1
pos = 0;
expr[pos] = '\0';
sum = 1;
for (i = 2; num / i >= i; i++) {
if (num % i == 0) {
pos += sprintf(expr + pos, "+%d", i);
printf(" %d", i);
sum += i;
do { num /= i; } while (num % i == 0);
}
}
if (num != 1) {
pos += sprintf(expr + pos, "+%d", num);
printf(" %d", num);
sum += num;
}
printf("\nSum of its factors: 1%s = %u\n", expr, sum);
return 0;
}
Test:
Input number: 0x7fffffff
Factors are: 1 2147483647
Sum of its factors: 1+2147483647 = 2147483648

Since you want to print all the prime factors twice, you should do that in a way so that you can avoid duplicated code. Here is an idea:
#include <stdio.h>
/* Return the smallest prime that is smaller than or equal to n */
/* Assumes that the argument is greater than 1 */
int getFirst(int n)
{
int i;
for(i = 2; i <= n; i++)
if(n % i == 0)
return i;
}
int main()
{
int num, x, tmp, sum=0;
scanf("%d", &num);
tmp = num;
printf("Factors are: ");
while(1) {
x = getFirst(tmp);
printf("%d ", x);
if (x == tmp) /* If we are at the last prime */
break;
tmp /= x;
}
printf("\n");
printf("Sum of factors is: ");
tmp = num;
while(1) {
x = getFirst(tmp);
printf("%d ", x);
sum += x;
if(x == tmp) /* If we are at the last prime */
break;
printf("+ ");
tmp /= x;
}
printf("= %d\n", sum);
}
But as has been pointed out in the comments. 1 is not a prime, and that's why I excluded it.

Related

How do I get rid of a space at the end of output?

Here is my code so far for producing Fibonacci numbers. I keep getting a zero because it it adding a space bar at the very end, but I need a space between numbers.
#include<stdio.h>
void fib(int);
int main()
{
int n = 0;
while (n <= 0 || n > 70)
{
printf("enter the value(between 0 and 70)");
scanf("%d", &n);
if (n <= 0 || n >= 70)
printf("wrong input\n");
}
fib(n);
return 0;
}
void fib(int n)
{
/* Declare an array to store Fibonacci numbers. */
int f[n]; // 1 extra to handle case, n = 0
int i;
/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;
printf("%d %d ", f[0], f[1]);
for (i = 2; i < n; i++)
{
f[i] = f[i - 1] + f[i - 2];
printf("%d ", f[i]);
}
}
Remove the trailing space in the first printf and print the space before instead of after the number in the loop.
printf("%d %d", f[0], f[1]);
for (i = 2; i < n; i++) {
f[i] = f[i - 1] + f[i - 2];
printf(" %d", f[i]);
}

Finding MAX and MIN of random numbers

I'm writing a program where the user enters numbers and the program will find MAX and MIN and the position of these numbers. I want to give the user a choice for the program to fill in the numbers for him using rand().
It's working almost perfectly: the program will find the MAX number with the position but the problem occurs when printing MIN number with position -- it always prints number 8 and position 1.
Where is the problem?
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct elementposition {
int min;
int max;
int positionMax;
int positionMin;
} elementposition;
int main() {
struct elementposition minmax;
srand(time(NULL));
int a[500], i;
int c = sizeof(a) / sizeof(a[0]);
char y;
printf("How many numbers you want to enter: ");
scanf("%d", &c);
minmax.positionMax = minmax.positionMin = 0;
printf("Want to fill with random numbers? (Y/N)");
scanf(" %c", &y);
if (y == 'Y' || y == 'y') {
for (i = 0; i < c; i++) {
a[i] = rand() % 10000 + 1;
if (minmax.max < a[i]) {
minmax.max = a[i];
minmax.positionMax = i;
}
if (minmax.min > a[i]) {
minmax.min = a[i];
minmax.positionMin = i;
}
}
for (i = 0; i < c; i++) {
printf("Number #%d: %d\n", i + 1, a[i]);
}
} else {
printf("------------------------------------ \n");
printf("Enter (%d) numbers: \n", c);
scanf("%d", &a[0]);
minmax.max = minmax.min = a[0];
for (i = 1; i < c; i++) {
scanf("%d", &a[i]);
if (minmax.max < a[i]) {
minmax.max = a[i];
minmax.positionMax = i;
}
if (minmax.min > a[i]) {
minmax.min = a[i];
minmax.positionMin = i;
}
}
}
printf("\nMax number is %d, number position %d. \n", minmax.max, minmax.positionMax + 1);
printf("Min number is %d, number position %d. \n", minmax.min, minmax.positionMin + 1);
printf("------------------------------------ \n");
getch();
return 0;
}
You never initialize minmax.min nor minmax.max in the random case. The code has undefined behavior because it depends on uninitialized values which may be anything, including trap values on some rare architectures.
You should separate the input/generation phase from the scanning phase and use a common loop for that. Also check that c is positive and does not exceed the length of the array.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct elementposition {
int min;
int max;
int positionMax;
int positionMin;
} elementposition;
int main() {
struct elementposition minmax;
int a[500];
int i, count, len = sizeof(a) / sizeof(a[0]);
char y = 'y';
printf("How many numbers you want to enter: ");
if (scanf("%d", &count) != 1 || count < 1 || count > len) {
printf("invalid count\n");
return 1;
}
printf("Want to fill with random numbers? (Y/N)");
scanf(" %c", &y);
if (y == 'Y' || y == 'y') {
srand(time(NULL));
for (i = 0; i < count; i++) {
a[i] = rand() % 10000 + 1;
printf("Number #%d: %d\n", i + 1, a[i]);
}
} else {
printf("Enter (%d) numbers:\n", c);
for (i = 0; i < count; i++) {
if (scanf("%d", &a[i]) != 1) {
printf("invalid input\n");
return 1;
}
}
}
minmax.positionMax = minmax.positionMin = 0;
minmax.max = minmax.min = a[0];
for (i = 1; i < count; i++) {
if (minmax.max < a[i]) {
minmax.max = a[i];
minmax.positionMax = i;
}
if (minmax.min > a[i]) {
minmax.min = a[i];
minmax.positionMin = i;
}
}
printf("------------------------------------\n");
printf("Max number is %d, number position %d.\n", minmax.max, minmax.positionMax + 1);
printf("Min number is %d, number position %d.\n", minmax.min, minmax.positionMin + 1);
printf("------------------------------------\n");
getch();
return 0;
}
You use minmax.min and minmax.max before initializing them. Here the problem for finding the min is probably that the minmax.min happens to initialy contain the value 8 and that all the values are greater.
The common way is to initialize the min to the highest possible value and max to the lowest one. As you use int values:
struct elementposition minmax = { INT_MAX, INT_MIN };
should be enough.

Why am I getting a wrong output for this code (to print the number of palindromes in an array)?

find the number of palindromes in an array
What I did was to first find out the number of digits of the number and then multiply the first remainder with the digit-1-th term and then remainder two with digit-2-th term and so on. if sum == num then it adds 1 to run.
#include <stdio.h>
#include <math.h>
int main() {
int a[30], i, n, cont = 0, j, rem, run = 0, sum = 0, b[300], c[300];
printf("Enter the number of elements\n");
scanf("%d", &n);
printf("Enter the array elements\n");
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 0; i < n; i++) {
c[i] = a[i];
b[i] = a[i];
cont = 0;
while (b[i] != 0) {
b[i] = b[i] / 10;
cont++;
}
sum = 0;
while (a[i] != 0) {
rem = a[i] % 10;
sum = sum + rem * pow(10, cont - 1);
cont--;
a[i] = a[i] / 10;
}
if (sum == c[i])
run++;
}
printf("%d\n", run);
}
is there any problem with the for and while loops?
Your programs works but several remarks can be done
check the result of scanf
check the range of n
you do not need arrays b and c and even you use them as array their size can be 30 as a
A proposal :
#include<stdio.h>
#include<math.h>
#define N 30
int main()
{
int a[N],i,n,run=0;
printf("Enter the number of elements\n");
if ((scanf("%d",&n) != 1) || (n < 1) || (n > N)) {
puts("invalid number of element");
return -1;
}
printf("Enter the array elements\n");
for(i=0;i<n;i++)
{
if (scanf("%d",&a[i]) != 1)
{
puts("invalid number");
i -= 1;
continue;
}
}
for(i=0;i<n;i++)
{
int b = a[i];
int cont=0;
while(b!=0)
{
b=b/10;
cont++;
}
int sum=0;
b = a[i];
while(b!=0)
{
int rem=b%10;
sum=sum+rem*pow(10,cont-1);
cont--;
b /= 10;
}
if(sum==a[i]) {
printf("%d is a palindrome\n", a[i]);
run++;
}
}
printf("%d\n",run);
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -pedantic -Wextra p.c -lm
pi#raspberrypi:/tmp $ ./a.out
Enter the number of elements
3
Enter the array elements
1
12
12321
1 is a palindrome
12321 is a palindrome
2
Note you can also read the numbers a string to be more general and avoid calculus

C Programming: How to add up divisors of an integer n

I was wondering, how can I add up the divisors displayed once I run my code?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i;
scanf("%d", &n);
for(i = 1; i < n; i++)
{
if(n % i == 0)
{
printf("%d\n", i);
}
}
return 0;
}
If I were to enter, say, 25, it would print out 1, 5. I was wondering how to add up the two numbers 1 and 5?
Could it be as simple as this? You will want to use a simple increment operator (+=), to increment the variable sum.
int main(void)
{
int n, i, sum = 0;
if( scanf("%d", &n)!= 1){
fprintf(stderr,"Error in input\n");
exit(EXIT_FAILURE);
}
for(i = 1; i < n; i++)
{
if(n % i == 0)
{
printf("%d\n", i);
sum += i;
}
}
printf("Sum of divisors: %d\n", sum);
return 0;
}
How to add up divisors of an integer n?
Iterating n times as with for(i = 1; i < n; i++) can take a long time when n is some high value, especially if code used 64-bit integers. Instead only iterate sqrt(n) times - much faster
int factor_count(int number) {
if (number <= 1) {
return TBD_Code(number); // OP needs to define functionality for these cases.
}
int sum = 1;
int quotient;
int divisor = 1;
do {
divisor++;
quotient = number/divisor;
int remainder = number%divisor;
if (remainder == 0) {
sum += divisor;
if (quotient > divisor) sum += quotient;
}
} while (divisor < quotient);
return sum;
}
Additional improvements noted here.

C program to print all numbers with different digits in interval

I need to make a program in C, which outputs all numbers with different digits in interval entered by the user. Here is what I've come up with.
#include<stdio.h>
int main(){
int n, m, k = 0, p, flag, last, temp;
do{
printf("Enter m and n (m < n):\n"); scanf("%d %d", &m, &n);
if (m < n) {
break;
}
else printf("\Error- m > n! Try again.\n\n");
} while (k == 0);
printf("Numbers are:\n");
for (k = m; k <= n; k++) {
p = k;
flag = 0;
if (p < 10) {
flag = 1;
}
last = (p / 10) % 10 ;
while (p > 0) {
temp = p % 10;
p = p / 10;
if (temp == last ){
flag = 1;
}
last = temp;
}
if (flag != 1) {
printf("%d ", k);
}
}
getch();
return 0;
}
Example output:
Enter m and n (m < n):
100 130
Numbers are:
101 102 103 104 105 106 107 108 109 120 121 123 124 125 126 127 128 129 130
So the problem in this case is that it outputs 101 and 121. It shouldn't because they have two same digits. How do I fix that?
I believe this is the solution you're looking for. If you convert the numbers into strings it will be easier to check their digits. Note that you need two loops per number in the sequence. It's concise but it's still expensive. (Compile it using the flag -std=c11.)
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Enter two non-negative numbers in ascending order:\n");
int min, max;
scanf("%d %d", &min, &max);
while(min < 0 || max < 0 || min > max)
{
printf("Invalid input! Please enter two non-negative numbers in ascending order:\n");
scanf("%d %d", &min, &max);
}
printf("The numbers without repeated digits in the interval [%d, %d] are:\n", min, max);
for(int n = min; n <= max; ++n)
{
char digits[32];
sprintf(digits, "%d", n);
int repeated = 0;
for(int i = 0; digits[i] && !repeated; ++i)
{
for(int j = i + 1; digits[j]; ++j)
{
if(digits[i] == digits[j])
{
repeated = 1;
break;
}
}
}
if(!repeated) printf("%d ", n);
}
printf("\n");
return 0;
}
Finally made it to work!
int main(){
int n, m, k = 0, p = 0, flag, i = 0, j, dig[10];
do{
printf("Enter m and n (m < n):\n"); scanf("%d %d", &m, &n);
if (m < n) {
break;
}
else printf("\Error- m > n! Try again.\n\n");
} while (k == 0);
printf("Numbers in the interval [%d, %d] are:\n", m, n);
for (k = m; k <= n; k++){
p = k;
flag = 0;
dig[i] = 0;
i = 0;
if (p < 10){
continue;
}
while (p > 0){
dig[i] = p % 10;
p = p / 10;
i++;
}
dig[i] = -1;
for (i = 0; dig[i] > -1; i++){
for (j = i + 1; dig[j] > -1; j++){
if (dig[i] == dig[j]){
flag = 1;
}
}
}
if (flag == 0){
printf("%d\t", k);
}
}
getch();
return 0;
}

Resources