(C) code cant work with all wanted conditions - c

#include <stdio.h>
#include <stdlib.h>
#define TEN 10
int main ()
{
int number = 0;
int digit = 0;
int last_digit = 0;
int digit_sum = 0;
int i = 0;
while (i == 0)
{
printf("Please Enter A Positive Number! \n"); //explaining
scanf("%d",&number);
if (number > 0)
{
i++;
}
}
while (number > 0)
{
digit = number % TEN; //breaking number into digits
number /= TEN;
if (last_digit != digit) //comparing digits
{
last_digit = digit;
digit_sum += digit;
}
}
printf("The Sum Of The Digits Is : %d",digit_sum);
return 0;
}
the code will divide the number into digits and check if there are duped digits, in case there are, only one of them will be calculated for exmple: 3211
3+2+1, but my problem is thats the code wont work with numbers like 31211 Im thankful for any kind of help.

The code doesn't work because there is no guarantee that duplicate's will appear consecutive manner. your code handles that not the other ways. That's why it fails.
A simple solution would be to consider a 10 element array where you will keep count of which element appeared and which didn't.
The idea is to map the digits to the array indices of the 10 element array. Intialized with 0.
...
int digitAppeared[10]={0};
while (number)
{
digit = number % TEN; //breaking number into digits
number /= TEN;
digit_sum += (1 - digitAppeared[digit]) * digit;
digitAppeared[digit] = 1;
}
...
To give you a clear idea this line basically checks whether the element appeared or not and as per the result it will add the digit.
If digit D appeared then digitAppeared[D]=1
and if it didn't then digitAppeared[D]=0.
We will add it to digitsum if it appears first time. That's why the (1-digitAppeared[D]) will tell us whether to add it or not.
digit_sum += (1 - digitAppeared[digit]) * digit;

Convert the number to string use itoa() . sort it and then walk through it , looking for unique number and do your calculation

You can mark which digits were already added by using setting logical flags as represented by done in program below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TEN 10
int main ()
{
int number = 0;
int digit = 0;
int last_digit = 0;
int digit_sum = 0;
int i = 0;
int done[10];
while (i == 0)
{
printf("Please Enter A Positive Number! \n"); //explaining
scanf("%d",&number);
if (number > 0)
{
i++;
}
}
memset(done,0,sizeof(done));
while (number > 0)
{
digit = number % TEN; //breaking number into digits
number /= TEN;
if(done[digit] == 0)
{
digit_sum += digit;
done[digit] = 1;
}
}
printf("The Sum Of The Digits Is : %d",digit_sum);
return 0;
}

Related

find sum of digits after decimal point

I want to find the sum of all the digits entered by a user after the decimal point in c.
Eg. 12.36 must return 9
15.06 must return 6
9.0 must return 0
My approach
#include <stdio.h>
int main()
{
double num,numfloat;
int digitf,numint,sumf=0;
scanf("%lf",&num);
numint=num;
numfloat=num-numint;
while(numfloat!=0)
{
digitf=(numfloat*10);
numfloat=numfloat*10-digitf;
sumf=sumf+digitf;
}
printf("Sum float %d",sumf);
return 0;
}
The sum comes out a lot more than the expected.
Try, (The reason why in this example, I haven't joined the loops is that: I want this to be usable on other situations where they use an alternate method of validating input, see the SECOND EXAMPLE for both loops joined):
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
// read from stdin
char num[512] = { };
fgets(num, sizeof(num), stdin);
num[strcspn(num, "\n")] = '\0';
// verify if number is valid
int decimal_point_found = 0;
for (int i = 0; i < strlen(num); i++) {
// check if digit
if (!isdigit(num[i])) {
// be safe from multiple decimal points
if (num[i] == '.' && decimal_point_found == 0) {
decimal_point_found = 1;
continue;
}
printf("ERROR: enter a valid number\n");
return 1;
}
}
int total = 0;
// add all the decimal points
for (int i = 0, decimal_point_found = 0; i < strlen(num); i++) {
if (decimal_point_found == 1) {
total += num[i] - '0'; // - '0' converts char to int
}
if (num[i] == '.') {
decimal_point_found = 1;
}
}
// show total
printf("%d\n", total);
}
In the above, I have read char instead of reading float. I have read using fgets() which is safer than scanf().
Handling char makes it so much easier to calculate such things. As we know the number of digits, etc.
With both loops joined:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
char num[512] = { };
fgets(num, 512, stdin);
num[strcspn(num, "\n")] = '\0';
// verify if number is valid
int decimal_point_found = 0;
int total = 0;
for (int i = 0; i < strlen(num); i++) {
if (!isdigit(num[i])) {
if (num[i] == '.' && decimal_point_found == 0) {
decimal_point_found = 1;
continue;
}
printf("ERROR: enter a valid number\n");
break;
}
if (decimal_point_found == 1) {
total += num[i] - '0';
}
}
printf("%d\n", total);
}
Original code fails as unless the fraction if exactly an integer/power-of-2, the input number, as decimal text, does not convert exactly to the same double. Instead num is the closet double possible. Yet that closest double may have many more digits when manipulated.
Further OP's numfloat=numfloat*10-digitf; injects repeated rounding errors.
Instead code needs to compensate for that rounding in some fashion.
the input has to be a number
Hmm, better to read in as a string, yet we can code a tolerable solution if we know the length of input by using "%n" to record the length of user input.
width below is the number of non-white-space characters in input. If we assume things like 1) sign only when negative, 2) no exponential 3) not infinity nor NAN, 4) no more than 15 significant digits 5) no more than 15 fraction digits --> then width will almost always*1 gives us what is needed to process num.
#include<stdio.h>
#include<math.h>
int sumFraction(void) {
int sum = 0;
double num;
int start, end;
if (scanf(" %n%lf%n", &start, &num, &end) != 1) {
return -1;
}
if (num == 0) {
return 0;
}
int width = end - start;
if (num < 0) {
num = -num;
width--;
}
int p10 = (int) log10(num);
width--; // Decrement for the '.'
if (width > 15) {
printf("Too many leading digits\n");
return -1;
}
width -= (p10 + 1);
// Only care about fractional part
double ipart;
num = modf(num, &ipart);
if (num == 0) {
return 0;
}
// assert(width >= 0);
num *= pow(10, width);
long long ival = llround(num); // Form an integer
while (width > 0) {
width--;
sum += ival % 10;
ival /= 10;
}
return sum;
}
int main() {
printf(" %d\n", sumFraction());
printf(" %d\n", sumFraction());
printf(" %d\n", sumFraction());
}
*1 IMO, code is not robust as the given limitation of not reading in as a string is not real for the real world. So here is a non-real solution.
You mentioned in a comment that the input has to be a number.
This first point to mention is that when coding, we are not manipulating such abstract things as numbers,
but imperfection representations of numbers. Think to the famous painting "This is not a pipe".
Same here, "This is not a number".
float, double and char* are all or can be all representations of numbers.
Depending on the context, one representation can be more suitable than others. Here, using a char* is the best solution, has no internal conversion error occurs.
Now, let us assume that the input format double is imposed by your professor.
Why is your code not working? Mainly because internally, the representation of the numbers is generally imperfect.
A small error can lead to a large error when converting a float to an integer.
For example, int i = 0.999999 will give i = 0.
The solution is to account for the internal error representation, by introducing a margin, e.g. eps = 1.0e-14,
when performing the float-to-integer conversion, or when testing if a number is equal to 0.
A difficulty is that the internal error is multiplied by 10 when the number is multiplied by 10. So the value of epshas to be updated accordingly.
Moreover, we have to take into accout that the mantissa provides a relative accurracy only, not an absolute one.
Therefore, the eps value must be increased when the number is large.
0.123456789 --> 45
19.1 -> 1
12.45e-36 -> 12
12345.973 -> 19
0.83 -> 11
#include <stdio.h>
int main() {
double num, numfloat;
int digitf, numint, sumf = 0;
double eps = 1.0e-14; // to deal with representation inaccuracy of numbers
if (scanf("%lf", &num) != 1) return 1;
printf("number in memory: %.20g\n", num);
if (num < 0.0) num = -num;
numint = (int) (num + eps);
numfloat = num - numint;
int deal_with_low_number = numint == 0;
while (numint) { // the mantissa only proposes a relative accurracy ...
eps *= 10;
numint /= 10;
}
while (numfloat > eps || deal_with_low_number) {
numfloat *= 10;
digitf = (int) (numfloat + eps);
numfloat -= digitf;
sumf = sumf + digitf;
if (digitf != 0) deal_with_low_number = 0;
if (!deal_with_low_number) eps *= 10;
}
printf("Sum float %d\n", sumf);
return 0;
}

Calculate the sum of digits. If the number repeats itself, do not calculate it [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
My question is how do I check if a digit is repeated in an integer without using arrays?
For example: 123145... 1 is repeated twice. so the output should be 15 (1+2+3+4+5)
My current code is:
# include "stdio.h"
int main () {
int input = 0;
int sum = 0;
int input = 0;
int sum = 0;
int digit;
printf("Please enter a number: ");
scanf("%d" ,&input);
while(input > 0) {
digit = input % 10;
if(d0 < 1) {
sum += digit;
d0 = 1;
}
input /= 10;
}
printf("Sum of different digits is: %d\n", sum);
return 0;
}
This is a really dumb way to solve this problem, but it uses neither arrays nor bit vectors:
#include <stdbool.h>
bool numberHasDigit(unsigned n, unsigned digit) {
while (n) {
if (n % 10 == digit) return true;
n /= 10;
}
return false;
}
unsigned sumOfUniqueDigits(unsigned n) {
unsigned sum = 0;
for (unsigned digit = 1; digit <= 9; ++digit) {
if (numberHasDigit(n, digit)) sum += digit;
}
return sum;
}
It's dumb because using an array (or bit vector) of flags is much faster, particularly for big numbers, and the code is just as simple:
unsigned sumOfUniqueDigits(unsigned n) {
bool seen[10] = {false};
unsigned sum = 0;
while (n) {
unsigned digit = n % 10;
if (!seen[digit]) {
sum += digit;
seen[digit] = true;
}
n = n / 10;
}
return sum;
}
I have avoided for loops and arrays and function calls.
Basically, we run a while loop that looks at the 9 interesting digits (1,2,3,4,5,6,7,8,9).
While looking at each digit, we run another while loop to see if the current digit is in the number by using your modulus and division looping. If the digit is in the number, then we add it to the sum.
We only look at each digit one time, so duplicates are ignored.
# include "stdio.h"
int main()
{
int input = 0;
int sum = 0;
printf("Please enter a number: ");
scanf("%d", &input);
//, now, subtract those values that do not exist in your number
int digit = 1; // start at 1, since 0 does not add to the sum
while (digit < 10) {
// check to see if the digit is in the number
int testInput = input;
while (testInput > 0) {
if (testInput % 10 == digit) {
sum += digit;
break; // Don't test for this digit any more, so go back to the outer loop.
}
testInput /= 10;
}
digit++; // increment the digit
}
printf("Sum of different digits is: %d\n", sum);
return 0;
}
A variation on the #rici good answer (and written as a one function call as #John Murray) with reduced operations - on average about 2x faster.
Rather than iterate 1 to 9, it looks for a repeat of the least significant digit in the rest of the number.
unsigned SumUniqueDigits(unsigned n) {
unsigned sum = 0;
while (n) {
unsigned lsdigit = n % 10;
n /= 10;
unsigned mssdigits = n;
while (mssdigits) {
if (mssdigits % 10 == lsdigit) {
lsdigit = 0;
break;
}
mssdigits /= 10;
}
sum += lsdigit;
}
return sum;
}
Alternative even faster: On re-examination - failed test code. Removed.

Finding numbers with unique digits in C

I have to write a program that finds every number (except 0) which can be factored by numbers from 2-9.
For example first such a number would be number 2520 as it can be divided by every single number from 2 to 9.
It also has to be a number that contains only 1 type of digit of its own (no multiple digits in a number). So for example 2520 will not meet this requirement since there are two same digits (2). The example of a number that meets both requirements is number 7560. That is the point I don't how to do it. I was thinking about converting value in an array to string, and then putting this string in another array so every digit would be represented by one array entry.
#include <stdio.h>
#include <math.h>
int main() {
int i, n, x, flag, y = 0;
scanf("%d", &n);
double z = pow(10, n) - 1;
int array[(int)z];
for (i = 0; i <= z; i++) {
flag = 0;
array[i] = i;
if (i > 0) {
for (x = 2; x <= 9; x++) {
if (array[i] % x != 0) {
flag = 1;
}
}
if (flag == 0) {
y = 1;
printf("%d\n", array[i]);
}
}
}
if (y == 0) {
printf("not exist");
}
return 0;
}
This should give you a base:
#include <stdio.h>
#include <string.h>
int main()
{
char snumber[20];
int number = 11235;
printf("Number = %d\n\n", number);
sprintf(snumber, "%d", number);
int histogram[10] = { 0 };
int len = strlen(snumber);
for (int i = 0; i < len; i++)
{
histogram[snumber[i] - '0']++;
}
for (int i = 0; i < 10; i++)
{
if (histogram[i] != 0)
printf("%d occurs %d times\n", i, histogram[i]);
}
}
Output:
Number = 11235
1 occurs 2 times
2 occurs 1 times
3 occurs 1 times
5 occurs 1 times
That code is a mess. Let's bin it.
Theorem: Any number that divides all numbers in the range 2 to 9 is a
multiple of 2520.
Therefore your algorithm takes the form
for (long i = 2520; i <= 9876543210 /*Beyond this there must be a duplicate*/; i += 2520){
// ToDo - reject if `i` contains one or more of the same digit.
}
For the ToDo part, see How to write a code to detect duplicate digits of any given number in C++?. Granted, it's C++, but the accepted answer ports verbatim.
If i understand correctly, your problem is that you need to identify whether a number is consisted of multiple digits.
Following your proposed approach, to convert the number into a string and use an array to represent digits, i can suggest the following solution for a function that implements it. The main function is used to test the has_repeated_digits function. It just shows a way to do it.
You can alter it and use it in your code.
#include <stdio.h>
#define MAX_DIGITS_IN_NUM 20
//returns 1 when there are repeated digits, 0 otherwise
int has_repeated_digits(int num){
// in array, array[0] represents how many times the '0' is found
// array[1], how many times '1' is found etc...
int array[10] = {0,0,0,0,0,0,0,0,0,0};
char num_string[MAX_DIGITS_IN_NUM];
//converts the number to string and stores it in num_string
sprintf(num_string, "%d", num);
int i = 0;
while (num_string[i] != '\0'){
//if a digit is found more than one time, return 1.
if (++array[num_string[i] - '0'] >= 2){
return 1; //found repeated digit
}
i++;
}
return 0; //no repeated digits found
}
// test tha function
int main()
{
int x=0;
while (scanf("%d", &x) != EOF){
if (has_repeated_digits(x))
printf("repeated digits found!\n");
else
printf("no repeated digits\n");
}
return 0;
}
You can simplify your problem from these remarks:
the least common multiple of 2, 3, 4, 5, 6, 7, 8 and 9 is 2520.
numbers larger than 9876543210 must have at least twice the same digit in their base 10 representation.
checking for duplicate digits can be done by counting the remainders of successive divisions by 10.
A simple approach is therefore to enumerate multiples of 2520 up to 9876543210 and select the numbers that have no duplicate digits.
Type unsigned long long is guaranteed to be large enough to represent all values to enumerate, but neither int nor long are.
Here is the code:
#include <stdio.h>
int main(void) {
unsigned long long i, n;
for (n = 2520; n <= 9876543210; n += 2520) {
int digits[10] = { 0 };
for (i = n; i != 0; i /= 10) {
if (digits[i % 10]++)
break;
}
if (i == 0)
printf("%llu\n", n);
}
return 0;
}
This program produces 13818 numbers in 0.076 seconds. The first one is 7560 and the last one is 9876351240.
The number 0 technically does match your constraints: it is evenly divisible by all non zero integers and it has no duplicate digits. But you excluded it explicitly.

Finding Twin Primes - Have logic finished, but it won't print anything when the program is ran

A twin prime is a prime number that is exactly two larger than the largest prime number that is smaller than it. For example, 7 is a twin prime because it is exactly two larger than 5. But 17 is not a twin prime because the largest prime less than 17 is 13.
My logic for this program is as follows:
*ask number of twin primes that want to be found
*loop until desired number of twin primes are found
*loop numbers 2 - 1million (declared as variable j)
*check if that number 'j' is prime - if so flag it
*if 'j' is not flagged, subtract 2 from 'j' (call that new number 'TPcheck')
*Check if 'TPcheck' is a prime, if so, print 'TPcheck' and the first number 'j'
When I run this program, I enter the number of twin primes to be found, but it just continues to run, and doesn't print anything on the screen. I think that the problem may have something to do with the order of the loops and if statements(or maybe the way that they are nested), but I have tried a ton of different ways and nothing has worked.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 2, count = 0, TPcheck, j, k, flag;
int numberofTwinPrimes;
printf("Enter how many twin primes you want to find");
scanf("%d", &numberofTwinPrimes);
while(count < numberofTwinPrimes)
{
for(j = 2; j <= 1000000; ++j)
{ for(i = 2; i < j; ++i)
{
if(j%i == 0)
{
flag = 1;
continue;
}
if(flag == 0)
{
TPcheck = j - 2;
for(k = 2; k < TPcheck; ++k)
{
if(TPcheck%k == 0)
{
flag = 1;
continue;
}
if(flag == 0)
{
printf("%d\t %d\t", TPcheck, j);
count++;
}
}
}
}
}
}
return 0;
}
I think your code can be simplified quite a bit.
Define a function that simply returns whether a number is a prime number or not.
Use that in a loop using a very simple logic.
Here's a working version.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int isPrime(int n)
{
int stop = 0;
int i = 0;
// Special case for 3.
if ( n == 3 )
{
return 1;
}
// If n is not divisible by numbers up to sqrt(n),
// then, n is a prime number.
stop = (int)(sqrt(n));
// We can start at 3 and increment by 2
// There is no point dividing by even numbers.
for ( i = 3; i <= stop; i +=2 )
{
if ( n%i == 0 )
{
// It is not a prime number.
return 0;
}
}
// Checked divisibility by all numbers up to sqrt(n)
// This is a prime number.
return 1;
}
int main()
{
int i = 0;
int count = 0;
int numberofTwinPrimes;
printf("Enter how many twin primes you want to find: ");
scanf("%d", &numberofTwinPrimes);
// Start checking at 3 and increment by 2.
// There is no point checking even numbers.
// When we find the required number of twin primes, stop.
for(i = 3; i <= 1000000 && count < numberofTwinPrimes; i += 2 )
{
if ( isPrime(i) && isPrime(i+2) )
{
++count;
printf("%d\t %d\n", i, i+2);
}
}
return 0;
}
Here's the output when numberOfTwinPrimes is 10.
3 5
5 7
11 13
17 19
29 31
41 43
59 61
71 73
101 103
107 109
This isPrime() function is faster than Fumu's suggestion:
/* function isPrime returns True if argument is prime number. */
boolean isPrime(int aNumber)
{
int i;
int limit;
/* Numbers < 2 */
if(aNumber < 2) { return False; }
/* Even numbers. */
if (aNumber % 2 == 0) { return aNumber == 2; }
/* Odd numbers. */
/* Only need to check odd divisors as far as the square root. */
limit = (int)(sqrt(aNumber));
for (i = 3; i <= limit; i += 2)
{
if( aNumber % i == 0) { return False; }
}
/* Only prime numbers make it this far. */
return True;
}
Two is the only even prime, so all even numbers can be dealt with very quickly. Odd numbers only need to be tested with odd divisors less than or equal to the square root of the number: 9 = 3 * 3
There are faster methods, but they require construction of a table of primes. For your program, something like this appears to be sufficient.
Your code for checking a number is prime or not is not correct.
You should check the number never be divided any numbers less than the number.
Code of a function for checking a numer is prime or not is as follows:
/* function isPrime returns True if argument is prime number. */
boolean isPrime(int aNumber)
{
int i;
if(aNumber < 2) { return False; }
else if (aNumber==2) {return True;}
for i=2 to aNumber-1
{
if((aNumber%i) == 0){
return False;
}
}
return True;
}
I hope this give you some useful idea.

generating armstrong number to nth number in c not working

I am trying to generate armstrong number to nth number.So,I have written a code for that,but it is not working.Everytime I input a number like 999 or 10000,it return only 0....can anyone please help me to find out what's wrong with this code:
#include <stdio.h>
#include <math.h>
int main()
{
double remainder,n=0;
int number,sum = 0,q,x,count;
printf("Enter an integer upto which you want to find armstrong numbers:");
scanf("%d",&number);
printf("\nFollowing armstrong numbers are found from 1 to %d\n",number);
for( count = 1 ; count <= number ; count++ )
{
q = count;
x = count;
for(;x != 0;)
{
x =x / 10;
n = n + 1;
}
while(q != 0)
{
remainder = q % 10;
sum = sum +(pow(remainder,n));
q = q / 10;
}
if ( count == sum ){
printf("%d\n", count);
}
sum = 0;
}
return 0;
}
You have to initialize n to zero inside the loop for count. And take care of proper rounding of the result of pow by for example adding 0.5 to it.

Resources