Print a different result than actual answer (Ciel and A-B Problem) - c

Input:
An input contains 2 integers A and B.
Output:
Print a wrong answer of A-B. Your answer must be a positive integer containing the same number of digits as the correct answer, and exactly one digit must differ from the correct answer. Leading zeros are not allowed. If there are multiple answers satisfying the above conditions, anyone will do.
Code:
#include <stdio.h>
int no_of_zeroes(int x);
int main()
{
int a, b;
int res1, res2;
int n1, n2;
scanf("%d",&a);
scanf("%d",&b);
res1 = a - b;
res2 = res1 + 10;
n1 = no_of_zeroes(res1);
n2 = no_of_zeroes(res2);
if(res1 < 9) printf("%d",res1 + 1);
else if(res1 == 9) printf("%d",res1-1);
else if((n1 == n2) && (res1 > 9)) printf("%d",res2);
else if((n2 > n1) && (res1>9))
{
res2 = res2 - 20;
printf("%d",res2);
}
}
int no_of_zeroes(int x)
{
int count = 0;
while(x>0)
{
x = x / 10;
count++;
}
return count;
}
Error:
What different should i do, basically else if blocks are creating trouble.

Your answer must be a positive integer containing the same number of digits as the correct answer
So the answer should be a-b. But the statement also says
exactly one digit must differ from the correct answer
Since it didn't specify the position of the digit, changing the last digit only should give us the correct answer to this problem. And so counting the number of digits of the difference is redundant.
Now the issue is - how to change the last digit? It's simple. We add 1 to the difference.
But there is a catch! If the difference is 99 and we add 1 to it, the result will be 100. Here, not only we're changing more than one digit, but also the number of digits.
And so, all we have to do is subtract 1 from the difference if the last digit of the difference is 9.
And so, the if-else block should look something like this:
int diff = a - b;
if(diff%10 == 9) {
diff--;
}
else {
diff++;
}
Here's my full code:
#include <stdio.h>
int main(void) {
int a, b;
scanf("%d%d", &a, &b);
int diff = a - b;
if(diff%10 == 9) {
diff--;
}
else {
diff++;
}
printf("%d\n", diff);
return 0;
}
On a different note, the function no_of_zeroes(int x) will return 0 if x=0. But, it should return 1 under general circumstances. And so the function should be something like this:
int no_of_digits(int x)
{
/* Adding the following line should fix the issue */
if(x==0) return 1;
int count = 0;
while(x>0)
{
x = x / 10;
count++;
}
return count;
}

I think you are making this much more complicated than needed. All you need is to check the last digit of the correct result and then change it.
For 0 and positive numbers:
last digit is 0 : add 1
last digit is 1 : add 1
...
last digit is 8 : add 1
last digit is 9 : subtract 1
For negative numbers, you simply change the sign and handle it as the positive number. This can be done because -123 has the same digits as 123.
So the code can be:
void wrongCalc(int a, int b)
{
int res = a - b; // Calculate result
if (res < 0) res = -res; // Change sign if negative
int lastDigit = res % 10; // Find last digit
if (lastDigit == 9)
{
--res; // Subtract 1
}
else
{
++res; // Add 1
}
printf("%d - %d = %d (correct result is %d)\n", a, b, res, a-b);
}
Limitations:
1) The program doesn't handle the possible integer overflow in a-b
2) The program doesn't handle the possible integer overflow in res = -res;
3) The program doesn't handle the case where the correct result is INT_MAX

Related

finding how many times number2 is showing in number1

I am solving an exercise in C and I got stuck. I don't know the logic of the code to get to my solution. For example we enter 2 numbers from input let the numbers be 123451289 and 12 and I want to see how many times number 2 is showing at number 1 (if this is confusing let me know). For the numbers earlier the program outputs 2. I tried solving it here is my code:
#include <stdio.h>
int main() {
int num1, num2, counter = 0;
scanf("%d%d", num1, num2);
if (num1 < num2) {
int temp = num1;
num1 = num2;
num2 = temp;
}
int copy1 = num1;
int copy2 = num2;
while (copy2 > 0) {
counter++; // GETTING THE LENGHT OF THE SECOND NUMBER
copy2 /= 10;
// lastdigits = copy1 % counter //HERE I WANT TO GET THE LAST DIGITS OF THE FIRST NUMBER
// But it does not work
}
}
My question is how can I get the last digits of the first number according to the second one for example if the second number have 3 digits I want to get the last 3 digits of the first number. For the other part I think I can figure it out.
I must solve this problem WITHOUT USING ARRAYS.
The problem: find all the needles (e.g. 12) in a haystack (e.g. 123451289).
This can be done simply without arrays using a modulus of the needle. For 12, this is 100. That is, 12 is two digits wide. Using the modulus, we can
isolate the rightmost N digits of the haystack and compare them against the needle.
We "scan" haystack repeatedly by dividing by 10 until we reach zero.
Here is the code:
#include <stdio.h>
int
main(void)
{
int need, hay, counter = 0;
scanf(" %d %d", &hay, &need);
// ensure that the numbers are _not_ reversed
if (hay < need) {
int temp = need;
need = hay;
hay = temp;
}
// get modulus for needle (similar to number of digits)
int mod = 1;
for (int copy = need; copy != 0; copy /= 10)
mod *= 10;
// search haystack for occurences of needle
// examine the rightmost "mod" digits of haystack and check for match
// reduce haystack digit by digit
for (int copy = hay; copy != 0; copy /= 10) {
if ((copy % mod) == need)
++counter;
}
printf("%d appears in %d exactly %d times\n",need,hay,counter);
return 0;
}
UPDATE:
I'm afraid this does not work for 10 0. –
chqrlie
A one line fix for to the modulus calculation for the 10/0 case. But, I've had to add a special case for the 0/0 input.
Also, I've added a fix for negative numbers and allowed multiple lines of input:
#include <stdio.h>
int
main(void)
{
int need, hay, counter;
while (scanf(" %d %d", &hay, &need) == 2) {
counter = 0;
// we can scan for -12 in -1237812
if (hay < 0)
hay = -hay;
if (need < 0)
need = -need;
// ensure that the numbers are _not_ reversed
if (hay < need) {
int temp = need;
need = hay;
hay = temp;
}
// get modulus for needle (similar to number of digits)
int mod = need ? 1 : 10;
for (int copy = need; copy != 0; copy /= 10)
mod *= 10;
// search haystack for occurences of needle
// examine the rightmost "mod" digits of haystack and check for match
// reduce haystack digit by digit
for (int copy = hay; copy != 0; copy /= 10) {
if ((copy % mod) == need)
++counter;
}
// special case for 0/0 [yecch]
if ((hay == 0) && (need == 0))
counter = 1;
printf("%d appears in %d exactly %d times\n", need, hay, counter);
}
return 0;
}
Here is the program output:
12 appears in 123451289 exactly 2 times
0 appears in 10 exactly 1 times
0 appears in 0 exactly 1 times
UPDATE #2:
Good fixes, including tests for negative numbers... but I'm afraid large numbers still pose a problem, such as 2000000000 2000000000 and -2147483648 8 –
chqrlie
Since OP has already posted an answer, this is bit like beating a dead horse, but I'll take one last attempt.
I've changed from calculating a modulus of needle into calculating the number of digits in needle. This is similar to the approach of some of the other answers.
Then, the comparison is now done digit by digit from the right.
I've also switched to unsigned and allow for the number to be __int128 if desired/supported with a compile option.
I've added functions to decode and print numbers so it works even without libc support for 128 bit numbers.
I may be ignoring [yet] another edge case, but this is an academic problem (e.g. we can't use arrays) and my solution is to just use larger types for the numbers. If we could use arrays, we'd keep things as strings and this would be similar to using strstr.
Anyway, here's the code:
#include <stdio.h>
#ifndef NUM
#define NUM long long
#endif
typedef unsigned NUM num_t;
FILE *xfin;
int
numget(num_t *ret)
{
int chr;
num_t acc = 0;
int found = 0;
while (1) {
chr = fgetc(xfin);
if (chr == EOF)
break;
if ((chr == '\n') || (chr == ' ')) {
if (found)
break;
}
if ((chr >= '0') && (chr <= '9')) {
found = 1;
acc *= 10;
chr -= '0';
acc += chr;
}
}
*ret = acc;
return found;
}
#define STRMAX 16
#define STRLEN 100
const char *
numprt(num_t val)
{
static char strbuf[STRMAX][STRLEN];
static int stridx = 0;
int dig;
char *buf;
buf = strbuf[stridx++];
stridx %= STRMAX;
char *rhs = buf;
do {
if (val == 0) {
*rhs++ = '0';
break;
}
for (; val != 0; val /= 10, ++rhs) {
dig = val % 10;
*rhs = dig + '0';
}
} while (0);
*rhs = 0;
if (rhs > buf)
--rhs;
for (char *lhs = buf; lhs < rhs; ++lhs, --rhs) {
char tmp = *lhs;
*lhs = *rhs;
*rhs = tmp;
}
return buf;
}
int
main(int argc,char **argv)
{
num_t need, hay, counter;
--argc;
++argv;
if (argc > 0)
xfin = fopen(*argv,"r");
else
xfin = stdin;
while (1) {
if (! numget(&hay))
break;
if (! numget(&need))
break;
counter = 0;
// we can scan for -12 in -1237812
if (hay < 0)
hay = -hay;
if (need < 0)
need = -need;
// ensure that the numbers are _not_ reversed
if (hay < need) {
num_t temp = need;
need = hay;
hay = temp;
}
// get number of digits in needle (zero has one digit)
int ndig = 0;
for (num_t copy = need; copy != 0; copy /= 10)
ndig += 1;
if (ndig == 0)
ndig = 1;
// search haystack for occurences of needle
// starting from the right compare digit-by-digit
// "shift" haystack right on each iteration
num_t hay2 = hay;
for (; hay2 != 0; hay2 /= 10) {
num_t hcopy = hay2;
// do the rightmost ndig digits match in both numbers?
int idig = ndig;
int match = 0;
for (num_t need2 = need; idig != 0;
--idig, need2 /= 10, hcopy /= 10) {
// get single current digits from each number
int hdig = hcopy % 10;
int ndig = need2 % 10;
// do they match
match = (hdig == ndig);
if (! match)
break;
}
counter += match;
}
// special case for 0/0 et. al. [yecch]
if (hay == need)
counter = 1;
printf("%s appears in %s exactly %s times\n",
numprt(need), numprt(hay), numprt(counter));
}
return 0;
}
Here's the program output:
12 appears in 123451289 exactly 2 times
123 appears in 123451289 exactly 1 times
1234 appears in 123451289 exactly 1 times
1 appears in 123451289 exactly 2 times
0 appears in 10 exactly 1 times
0 appears in 0 exactly 1 times
1000000000 appears in 1000000000 exactly 1 times
2000000000 appears in 2000000000 exactly 1 times
This looks along the lines of what you're attempting.
You can use the pow() function from math.h to raise 10 to the power of how many digits you need for your modulus operation.
Compile with -lm or make your own function to calculate 10^num_digits
#include <stdio.h>
#include <math.h>
int main() {
int x = 123456789;
double num_digits = 3.0;
int last_digits = x % (int)pow(10.0, num_digits);
printf("x = %d\nLast %d Digits of x = %d\n", x, (int)num_digits, last_digits);
return 0;
}
Outputs:
x = 123456789
Last 3 Digits of x = 789
I think you are trying to ask :- if number1 = 1234567 and number2 = 673, then, length of number2 or number2 has 3 digits, so, you now want the last 3 digits in number1, i.e, '456', if I'm not wrong.
If that is the case, then, what you did to find the number of digits in num2 is correct, i.e,
while (copy2>0) {
counter++; // GETTING THE LENGHT OF THE SECOND NUMBER
copy2/=10;
}
you can do the same for number1 and find out its number of digits, then you can compare whether the number of digits in number2 is less than that in number1. Ex, 3 is less than number of digits in number1, so you can proceed further. Let's say number of digits in number1 is 7 and you want the last 3 digits, so you can do iterate over the digits in number1 till count of digits in number2 and pop out each last digit and store them in an array.
The code:
#include <stdio.h>
int main()
{
int num1,num2;
int count1 = 0, count2 = 0;
scanf("%d",&num1);
scanf("%d",&num2);
if(num1<num2){
int temp = num1;
num1 = num2;
num2 = temp;
}
int copy1 = num1;
int copy2 = num2;
while (copy1>0)
{
count1++;
copy1/=10;
}
while (copy2>0)
{
count2++;
copy2/=10;
}
// printf("num1 has %d digits and num2 has %d digits\n", count1, count2);
if (count1 >= count2)
{
int arr[count2];
int x = count2;
int p = num1;
int i = 0;
while (x > 0)
{
arr[i++] = p%10;
x --;
p/=10;
}
for (int j = 0; j < i; j++)
{
printf("%d ", arr[j]);
}
}
return 0;
}
output : 8 7 6
let's say, num1 = 12345678, num2 = 158, then arr = {8,7,6}.
You must determine the number of digits N of num2 and test if num1 ends with num2 modulo 10N.
Note these tricky issues:
you should not sort num1 and num2: If num2 is greater than num1, the count is obviously 0.
num2 has at least 1 digit even if it is 0.
if num1 and num2 are both 0, the count is 1.
if num2 is greater then INT_MAX / 10, the computation for mod would overflow, but there can only be one match, if num1 == num2.
it is unclear whether the count for 1111 11 should be 2 or 3. We will consider all matches, including overlapping ones.
to handle larger numbers, we shall use unsigned long long instead of int type.
Here is a modified version:
#include <limits.h>
#include <stdio.h>
int main() {
int counter = 0;
unsigned long long num1, num2;
if (scanf("%llu%llu", &num1, &num2) != 2) {
printf("invalid input\n");
return 1;
}
if (num1 == num2) {
/* special case for "0 0" */
counter = 1;
} else
if (num1 > num2 && num2 <= ULLONG_MAX / 10) {
unsigned long long copy1 = num1;
unsigned long long mod = 10;
while (mod < num2) {
mod *= 10;
}
while (copy1 > 0) {
if (copy1 % mod == num2)
counter++;
copy1 /= 10;
}
}
printf("count=%d\n", counter);
return 0;
}
Note that leading zeroes are not supported in either number: 101 01 should produce a count of 1 but after conversion by scanf(), the numbers are 101 and 1 leading to a count of 2. It is non trivial to handle leading zeroes as well as numbers larger than ULLONG_MAX without arrays.
This was the answer that i was looking for but thank you all for helping :)
#include <stdio.h>
#include <math.h>
int main(){
int num1,counter1,counter2,num2,temp,digit,copy1,copy2;
scanf("%d%d",&num1,&num2);
if(num1<num2){
temp = num1;
num1 = num2;
num2 = temp;
}
copy1 = num1;
copy2 = num2;
counter1 = counter2 = 0;
while (copy2>0) {
counter1++;
copy2/=10;
}
counter1 = pow(10,counter1);
if(num1> 1 && num2>1)
while (copy1>0) {
digit = copy1%counter1;
if(digit==num2){
counter2++;
}
copy1/=10;
} else{
if(num2<1){
while (copy1>0) {
digit = copy1%10;
if(digit==copy2){
counter2++;
}
copy1/=10;
}
}
}
printf("%d",counter2);
}

How do I reverse the order of the digits of an integer using recursion in C programming?

Problem statement :
Given a 32-bit signed integer, reverse digits of an integer.
Note: Assume we are dealing with an environment that could only store
integers within the 32-bit signed integer range: [ −2^31, 2^31 − 1]. For
the purpose of this problem, assume that your function returns 0 when
the reversed integer overflows.
I'm trying to implement the recursive function reverseRec(), It's working for smaller values but it's a mess for the edge cases.
int reverseRec(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverseRec(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
I've implemented non recursive function which is working just fine :
int reverse(int x)
{
long long val = 0;
do{
val = val*10 + (x%10);
x /= 10;
}while(x);
return (val < INT_MIN || val > INT_MAX) ? 0 : val;
}
Here I use variable val of long long type to check the result with MAX and MIN of signed int type but the description of the problem specifically mentioned that we need to deal within the range of 32-bit integer, although somehow it got accepted but I'm just curious If there is a way to implement a recursive function using only int datatype ?
One more thing even if I consider using long long I'm failing to implement it in the recursive function reverseRec().
If there is a way to implement a recursive function using only int datatype ?
(and) returns 0 when the reversed integer overflows
Yes.
For such +/- problems, I like to fold the int values to one side and negate as needed. The folding to one side (- or +) simplifies overflow detection as only a single side needs testing
I prefer folding to the negative side as there are more negatives, than positives. (With 32-bit int, really didn't make any difference for this problem.)
As code forms the reversed value, test if the following r * 10 + least_digit may overflow before doing it.
An int only recursive solution to reverse an int. Overflow returns 0.
#include <limits.h>
#include <stdio.h>
static int reverse_recurse(int i, int r) {
if (i) {
int least_digit = i % 10;
if (r <= INT_MIN / 10 && (r < INT_MIN / 10 || least_digit < INT_MIN % 10)) {
return 1; /// Overflow indication
}
r = reverse_recurse(i / 10, r * 10 + least_digit);
}
return r;
}
// Reverse an int, overflow returns 0
int reverse_int(int i) {
// Proceed with negative values, they have more range than + side
int r = reverse_recurse(i > 0 ? -i : i, 0);
if (r > 0) {
return 0;
}
if (i > 0) {
if (r < -INT_MAX) {
return 0;
}
r = -r;
}
return r;
}
Test
int main(void) {
int t[] = {0, 1, 42, 1234567890, 1234567892, INT_MAX, INT_MIN};
for (unsigned i = 0; i < sizeof t / sizeof t[0]; i++) {
printf("%11d %11d\n", t[i], reverse_int(t[i]));
if (t[i] != INT_MIN) {
printf("%11d %11d\n", -t[i], reverse_int(-t[i]));
}
}
}
Output
0 0
0 0
1 1
-1 -1
42 24
-42 -24
1234567890 987654321
-1234567890 -987654321
1234567892 0
-1234567892 0
2147483647 0
-2147483647 0
-2147483648 0
You could add a second parameter:
int reverseRec(int x, int reversed)
{
if(x == 0)
{
return reversed;
}
else
{
return reverseRec(x/10, reversed * 10 + x%10);
}
}
And call the function passing the 0 for the second parameter. If you want negative numbers you can check the sign before and pass the absolute value to this function.
In trying to learn C programming I programed this question and get some correct results and some incorrect. I don't see the reason for the difference.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h> // requires adding link to math -lm as in: gcc b.c -lm -o q11
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0) // if done returns value
{
return startValue;
}
int temp = startValue % 10; // gets units digit
int newStart = (startValue -temp)/10; // computes new starting value after removing one digit
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal); // calls itself recursively until done
}
int main()
{
int x, decimalP, startValue;
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
if (x > 214748364)
{
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
}
decimalP = round(log10(x)); // computes the number of powers of 10 - 0 being units etc.
startValue = ReverseInt(x, decimalP); // calls function with number to be reversed and powers of 10
printf("\n reverse of %d is %d \n", x, startValue);
}
Output is: reverse of 1234 is 4321 but then reverse of 4321 is 12340
It's late and nothing better does not come into my mind. No float calculations. Of course, integer has to be big enough to accommodate the result. Otherwise it is an UB.
int rev(int x, int partial, int *max)
{
int result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
int reverse(int x)
{
int max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d", reverse(-456789));
}
https://godbolt.org/z/M1eezf
unsigned rev(unsigned x, unsigned partial, unsigned *max)
{
unsigned result;
if(x / partial < 10)
{
*max = partial;
return (x % 10) * partial;
}
result = rev(x, partial * 10, max) + (x / (*max / partial) % 10) * partial;
return result;
}
unsigned reverse(unsigned x)
{
unsigned max;
return rev(x, 1, &max);
}
int main(void){
printf("%u", reverse(123456));
}
when using long long to store the result all possible integers can be reversed
long long rev(int x, long long partial, long long *max)
{
long long result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
long long reverse(int x)
{
long long max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d reversed %lld\n", INT_MIN, reverse(INT_MIN));
printf("%d reversed %lld\n", INT_MAX, reverse(INT_MAX));
}
https://godbolt.org/z/KMfbxz
I am assuming by reversing an integer you mean turning 129 to 921 or 120 to 21.
You need an initial method to initialize your recursive function.
Your recursive function must figure out how many decimal places your integer uses. This can be found by using log base 10 with the value and then converting the result to a integer.
log10 (103) approx. 2.04 => 2
Modulus the initial value by 10 to get the ones place and store it in a variable called temp
Subtract the ones place from the initial value and store that in a variable called newStart.
divide this value by 10
Subtract one from the decimal place and store in another variable called newDecimal.
Return the ones place times 10 to the power of the decimal place and add it to the function where the initial value is newStart and the decimalPlace is newDecimal.
#include <stdio.h>
#include <math.h>
int ReverseInt(int startValue, int decimalPlace);
int main()
{
int i = -54;
int positive = i < 0? i*-1 : i;
double d = log10(positive);
int output = ReverseInt(positive,(int)d);
int correctedOutput = i < 0? output*-1 : output;
printf("%d \n",correctedOutput);
return 0;
}
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0)
{
return startValue;
}
int temp = startValue % 10;
int newStart = (startValue -temp)/10;
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal);
}

Armstrong number program in C returns wrong value

I am writing a program to see if a user entered number is Armstrong or not, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int x = 0;
printf("Enter a natural number: ");
scanf("%d", &x);
int ans = x;
// Digit Counter
int counter = 0; //Variable for number of digits in the user entered number
int b = x; //For each time number can be divided by 10 and isnt 0
for (int i = 1; i <= x; i++){ // Then counter variable is incremented by 1
b /= 10;
if (b != 0){
counter += 1;
}
}
++counter;
//Digit Counter
int sum = 0;
// Digit Finder
int D;
for (int j = 1; j <= x; j++){
D = x % 10; //Shows remainder of number (last digit) when divided by 10
sum += pow(D, counter); //Raises Digit found by counter and adds to sum
printf("%d\n", sum);
x /= 10; // Divides user entered number by 10 to get rid of digit found
}
if (sum == ans){
printf("%d is a Armstrong number! :)", ans);
}else
printf("%d is not an Armstrong number :(", ans);
//Digit Finder
return 0;
}
My problem is that the program works fine apart from one point, when the program is given a Armstrong number which does not start with 1 then it behaves normally and indicates if it is an Armstrong number or not, but when i input a Armstrong number which start with 1 then it will print out the Armstrong number but -1.
For example: If i input something such as 371 which is an Armstrong number it will show that it is an Armstrong number. However if i input 1634 it will output 1633 which is 1 less than 1634.
How can i fix this problem?, also by the way could someone comment on my code and tell me if it seems good and professional/efficient because i am a beginner in C and would like someone else's opinion on my code.
How can I fix this problem.
You know the number of iterations you want to make once you have calculated the digit count. So instead of looping till you reach the value of x:
for (int j = 1; j <= x; j++){
use the digit counter instead:
for (int j = 1; j <= counter; j++) {
also by the way could someone comment on my code and tell me if it seems good and professional/efficient because i am a beginner in C and would like someone else's opinion on my code.
There's a number of things you can do to improve your code.
First and foremost, any piece of code should be properly indented and formatted. Right now your code has no indenting, which makes it more difficult to read and it just looks ugly in general. So, always indent your code properly. Use an IDE or a good text editor, it will help you.
Be consistent in your code style. If you are writing
if (some_cond) {
...
}
else
//do this
It is not consistent. Wrap the else in braces as well.
Always check the return value of a function you use, especially for scanf. It will save you from many bugs in the future.
if (scanf("%d", &x) == 1)
//...all OK...
else
// ...EOF or conversion failure...
exit(EXIT_FAILURE);
Your first for loop will iterate x times uselessly. You can stop when you know that you have hit 0:
for (int i = 1; i <= x; i++){ // Then counter variable is incremented by 1
b /= 10;
if (b == 0){
break;
}
counter += 1;
}
C has ++ operator. Use that instead of doing counter += 1
int D; you create this, but don't initialize it. Always initialize your variables as soon as possible
C has const qualifier keyword, which makes a value immutable. This makes your code more readable, as the reader can immediately tell that this value will not change. In your code, you can change ans variable and make it a const int because it never changes:
const int ans = x;
Use more descriptive names for your variables. ans, D don't tell me anything. Use proper names, so that the reader of your code can easily understand your code.
These are some of the things that in my opinion you should do and keep doing to improve your code and coding skills. I am sure there can be more things though. Keep your code readable and as simple as possible.
The condition in this loop
for (int i = 1; i <= x; i++){ // Then counter variable is incremented by 1
b /= 10;
if (b != 0){
counter += 1;
}
}
does not make sense because there will be numerous redundant iterations of the loop.
For example if x is equal to 153 that is contains only 3 digits the loop will iterate exactly 153 times.
Also additional increment of the variable counter after the loop
++counter;
makes the code logically inconsistent.
Instead of the loop you could write at least the following way
int counter = 0;
int b = x;
do
{
++counter;
} while ( b /= 10 );
This loop iterates exactly the number of times equal to the number of digits in a given number.
In this loop
for (int j = 1; j <= x; j++){
D = x % 10; //Shows remainder of number (last digit) when divided by 10
sum += pow(D, counter); //Raises Digit found by counter and adds to sum
printf("%d\n", sum);
x /= 10; // Divides user entered number by 10 to get rid of digit found
}
it seems you did not take into account that the variable x is decreased inside the body of the loop
x /= 10; // Divides user entered number by 10 to get rid of digit found
So the loop can interrupt its iterations too early. In any case the condition of the loop again does not make great sense the same way as the condition of the first loop and only adds a bug.
The type of used variables that store a given number should be unsigned integer type. Otherwise the user can enter a negative number.
You could write a separate function that checks whether a given number is an Armstrong number.
Here you are.
#include <stdio.h>
int is_armstrong( unsigned int x )
{
const unsigned int Base = 10;
size_t n = 0;
unsigned int tmp = x;
do
{
++n;
} while ( tmp /= Base );
unsigned int sum = 0;
tmp = x;
do
{
unsigned int digit = tmp % Base;
unsigned int power = digit;
for ( size_t i = 1; i < n; i++ ) power *= digit;
sum += power;
} while ( ( tmp /= Base ) != 0 && !( x < sum ) );
return tmp == 0 && x == sum;
}
int main(void)
{
unsigned int a[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407,
1634, 8208, 9474, 54748, 92727, 93084, 548834
};
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%u is %san Armstrong number.\n", a[i], is_armstrong( a[i] ) ? "": "not " );
}
return 0;
}
The program output is
0 is an Armstrong number.
1 is an Armstrong number.
2 is an Armstrong number.
3 is an Armstrong number.
4 is an Armstrong number.
5 is an Armstrong number.
6 is an Armstrong number.
7 is an Armstrong number.
8 is an Armstrong number.
9 is an Armstrong number.
153 is an Armstrong number.
370 is an Armstrong number.
371 is an Armstrong number.
407 is an Armstrong number.
1634 is an Armstrong number.
8208 is an Armstrong number.
9474 is an Armstrong number.
54748 is an Armstrong number.
92727 is an Armstrong number.
93084 is an Armstrong number.
548834 is an Armstrong number.
Please remove j++ from 2nd loop for (int j = 1; j <= x; j++)
I tried this:
void armstrong(int x)
{
// count digits
int counter = 0, temp = x, sum = 0;
while(temp != 0)
{
temp = temp/10;
++counter; // Note: pre increment faster
}
// printf("count %d\n",counter);
temp = x;
while(temp != 0)
{
sum += pow(temp % 10, counter);
temp = temp/10;
}
// printf("sum %d\n",sum);
if(x == sum)
{
printf("Armstrong\n");
}
else
{
printf("No Armstrong\n");
}
}
int main(){
armstrong(371);
armstrong(1634);
return 0;
}
Let's take this and add the ability to handle multiple numeric bases while we're at it. Why? BECAUSE WE CAN!!!! :-)
#include <stdio.h>
#include <math.h>
double log_base(int b, double n)
{
return log(n) / log((double)b);
}
int is_armstrong_number(int b, /* base */
int n)
{
int num_digits = trunc(log_base(b, (double)n)) + 1;
int sum = 0;
int remainder = n;
while(remainder > 0)
{
sum = sum + pow(remainder % b, num_digits);
remainder = (int) (remainder / b);
}
return sum == n;
}
int main()
{
printf("All the following are valid Armstrong numbers\n");
printf(" 407 base 10 - result = %d\n", is_armstrong_number(10, 407));
printf(" 0xEA1 base 16 - result = %d\n", is_armstrong_number(16, 0xEA1));
printf(" 371 base 10 - result = %d\n", is_armstrong_number(10, 371));
printf(" 1634 base 10 - result = %d\n", is_armstrong_number(10, 1634));
printf(" 0463 base 8 - result = %d\n", is_armstrong_number(8, 0463));
printf("All the following are NOT valid Armstrong numbers\n");
printf(" 123 base 10 - result = %d\n", is_armstrong_number(10, 123));
printf(" 0x2446 base 16 - result = %d\n", is_armstrong_number(16, 0x2446));
printf(" 022222 base 8 - result = %d\n", is_armstrong_number(8, 022222));
}
At the start of is_armstrong_number we compute the number of digits directly instead of looping through the number. We then loop through the digits of n in base b, summing up the value of the digit raised to the number of digits in the number, for the given numeric base. Once the remainder hits zero we know there are no more digits to compute and we return a flag indicating if the given number is an Armstrong number in the given base.

Counting carry operations

Can anybody tell me why my program keeps getting wrong answer? It must count the number of carry operations in a sum. I tried every testcase came to my mind. I didn't get wrong output.
Problem Description:
Children are taught to add multi-digit numbers from right-to-left one digit at a time. Many find the "carry" operation - in which a 1 is carried from one digit position to be added to the next - to be a significant challenge. Your job is to count the number of carry operations for each of a set of addition problems so that educators may assess their difficulty.
Input
Each line of input contains two unsigned integers less than 10 digits. The last line of input contains 0 0.
Output
For each line of input except the last you should compute and print the number of carry operations that would result from adding the two numbers, in the format shown below.
Sample Input
123 456
555 555
123 594
0 0
Sample Output
No carry operation.
3 carry operations.
1 carry operation.
Here's my current code:
#include<stdio.h>
int main()
{
unsigned long long int a,b,m,n,rem_m,rem_n,judge=0,sum,count;
while((scanf("%llu%llu",&m,&n))==2)
{
if(m==0 && n==0)
{
break;
}
count=0;
while(m!=0 && n!=0)
{
rem_m=m%10;
rem_n=n%10;
if(judge==1)
{
rem_m++;
}
sum = rem_m+rem_n;
judge=0;
if(sum>=10)
{
count++;
judge++;
}
m=m/10;
n=n/10;
}
if(count==0)
{
printf("No carry operation.\n");
}
else
{
printf("%llu carry operations.\n",count);
}
}
return 0;
}
count the number of carry operations in a sum
Asserting a,b are >= 0:
Terse solution
For fun :)
"ds" stands for digit sum.
int ds(int n){return n == 0 ? 0 : n%10 + ds(n/10);}
int numberOfCarryOperations(int a,int b){return (ds(a) + ds(b) - ds(a+b)) / 9;}
Readable
Here is a more readable variation.
int digitSum(int n)
{
int sum;
for (sum=0; n > 0; sum+=n%10,n/=10);
return sum;
}
int numberOfCarryOperations(int a,int b){
// a, b >= 0
return (digitSum(a) + digitSum(b) - digitSum(a+b)) / 9;
}
You can prove mathematically: every time you have a carry, the digitSum decreases by 9.
9, because we are in number system 10, so we "lose 10" on one digit if we have carry, and we gain +1 as the carry.
Pythonic version
I do not know how to do this in C, but in python it is easy to write a better digitSum function. In python we can easily create the list of digits from a number, and then just use sum() on it to get digitSum of the given number.
Here is a terse python one-liner solution:
def numberOfCarryOperations(a, b):
# f is the digitSum function
f=lambda n:sum(map(int,str(n)));return(f(a)+f(b)-f(a+b))/9
The loop condition is wrong. You want while(m!=0 || n!=0) (i.e. while at least one of them is not zero) instead of while(m!=0 && n!=0), otherwise the answer will be wrong for things like 999 9, it will incorrectly stop after one iteration and report 1 carry operation whereas the correct answer should be 3. Think of it like this: you only want to stop when both of them are 0, so the loop must continue as long as at least one of the numbers is not 0.
Also, you forgot to clean up judge after printing output. You need to clear it before reading input again, or you could mistakenly have judge == 1 from a previous computation that ended with a carry (the name choice for this variable seems odd to me, you should rename it to something more meaningful like carry, but it's not the main issue here).
a and b are unused (you should enable compiler warnings).
The sample output shows the word operation (as in, singular) when the count is 1; your program always writes operations (plural). If you're submitting this to an automatic judge, the code will not pass because the output does not match exactly the expected output. To fix that small little detail, replace this:
else
{
printf("%llu carry operations.\n",count);
}
With:
else
{
printf("%llu carry operation%s.\n",count, count > 1 ? "s" : "");
}
Here's the fixed version:
#include <stdio.h>
int main(void)
{
unsigned long long int m,n,rem_m,rem_n,judge=0,sum,count;
while((scanf("%llu%llu",&m,&n))==2)
{
if(m==0 && n==0)
{
break;
}
count=0;
/* We want || here, not && */
while(m!=0 || n!=0)
{
rem_m=m%10;
rem_n=n%10;
if(judge==1)
{
rem_m++;
}
sum = rem_m+rem_n;
judge=0;
if(sum>=10)
{
count++;
judge++;
}
m=m/10;
n=n/10;
}
/* Clean up for next iteration */
judge = 0;
if(count==0)
{
printf("No carry operation.\n");
}
else
{
printf("%llu carry operations.\n",count);
}
}
return 0;
}
A ruby solution would be:
def count_carry_operations x, y
return 0 if x == 0 && y == 0
count = 0
carry = 0
while true
return count if x == 0 && y == 0
while x != 0 || y != 0
xr = x % 10
yr = y % 10
xr += 1 if carry == 1
sum = xr + yr
carry = 0
if sum >= 10
count += 1
carry += 1
end
x /= 10
y /= 10
end
carry = 0
end
count
end
A java solution would be:
public class Main {
public static int carry_count=0,carry_number=0;
public static void main(String[] args) {
System.out.println(Carry(99511,512));
}
private static int Carry(int num1,int num2){
if(num1/10==0 || num2/10==0){
int sum=num1%10+num2%10+carry_number;
if(sum>=10){
carry_number=1;
carry_count++;
return Carry(num1/10,num2/10);
}else{
return carry_count;}
}else {
int sum=num1%10+num2%10+carry_number;
if(sum>=10){
carry_number=1;
carry_count++;
}else {
carry_number=0;
}
return Carry(num1/10,num2/10);
}
}
}
Java program for people interested
static int numberOfCarryOperations(int num1, int num2) {
int counter = 0;
int result1 = 0;
int result2 = 0;
int carryNum = 0;
while( num1 != 0 || num2 != 0) {
result1 = num1%10;
result2 = num2%10;
if(num1 > 0 ) {
num1 = num1/10;
}
if( num2 > 0) {
num2 = num2/10;
}
if( (result1 + result2+carryNum) > 9 ) {
counter++;
carryNum = 1;
} else {
carryNum = 0;
}
}
return counter;
}
public static void main(String[] args) {
System.out.println(numberOfCarryOperations(123, 456)); // 0
System.out.println(numberOfCarryOperations(555, 555)); // 3
System.out.println(numberOfCarryOperations(900, 11)); // 0
System.out.println(numberOfCarryOperations(145, 55)); // 2
System.out.println(numberOfCarryOperations(0, 0));// 0
System.out.println(numberOfCarryOperations(1, 99999) );// 5
System.out.println(numberOfCarryOperations(999045, 1055) );// 5
System.out.println(numberOfCarryOperations(101, 809)); // 1
System.out.println(numberOfCarryOperations(189, 209) );// 1
}

Extracting individual digits from a long in C

I'm doing a homework assignment for my course in C (first programming course).
Part of the assignment is to write code so that a user inputs a number up to 9 digits long, and the program needs to determine whether this number is "increasing"/"truly increasing"/"decreasing"/"truly decreasing"/"increasing and decreasing"/"truly decreasing and truly increasing"/"not decreasing and not increasing". (7 options in total)
Since this is our first assignment we're not allowed to use anything besides what was taught in class:
do-while, for, while loops, else-if, if,
break,continue
scanf, printf ,modulo, and the basic operators
(We can't use any library besides for stdio.h)
That's it. I can't use arrays or getchar or any of that stuff. The only function I can use to receive input from the user is scanf.
So far I've already written the algorithm with a flowchart and everything, but I need to separate the user's input into it's distinct digits.
For example, if the user inputs "1234..." i want to save 1 in a, 2 in b, and so on, and then make comparisons between all the digits to determine for example whether they are all equal (increasing and decreasing) or whether a > b >c ... (decreasing) and so on.
I know how to separate each digit by using the % and / operator, but I can't figure out how to "save" these values in a variable that I can later use for the comparisons.
This is what I have so far:
printf("Enter a positive number : ");
do {
scanf ("%ld", &number);
if (number < 0) {
printf ("invalid input...enter a positive integer: ");
continue;
}
else break;
} while (1);
while (number < 0) {
a = number % 10;
number = number - a;
number = number / 10;
b = a;
}
Why not scan them as characters (string)? Then you can access them via an array offset, by subtracting the offset of 48 from the ASCII character code. You can verify that the character is a digit using isdigit from ctype.h.
EDIT
Because of the incredibly absent-minded limitations that your professor put in place:
#include <stdio.h>
int main()
{
int number;
printf("Enter a positive number: ");
do
{
scanf ("%ld", &number);
if (number < 0)
{
printf ("invalid input...enter a positive integer: ");
continue;
}
else break;
} while (1);
int a = -1;
int b = -1;
int c = -1;
int d = -1;
int e = -1;
int f = -1;
int g = -1;
int h = -1;
int i = -1;
while (number > 0)
{
if (a < 0) a = number % 10;
else if (b < 0) b = number % 10;
else if (c < 0) c = number % 10;
else if (d < 0) d = number % 10;
else if (e < 0) e = number % 10;
else if (f < 0) f = number % 10;
else if (g < 0) g = number % 10;
else if (h < 0) h = number % 10;
else if (i < 0) i = number % 10;
number /= 10;
}
/* Printing for verification. */
printf("%i", a);
printf("%i", b);
printf("%i", c);
printf("%i", d);
printf("%i", e);
printf("%i", f);
printf("%i", g);
printf("%i", h);
printf("%i", i);
return 0;
}
The valid numbers at the end will be positive, so those are the ones you validate to meet your different conditions.
Since you only need to compare consecutive digits, there is an elegant way to do this without arrays:
int decreasing = 2;
int increasing = 2;
while(number > 9)
{
int a = number % 10;
int b = (number / 10) % 10;
if(a == b)
{
decreasing = min(1, decreasing);
increasing = min(1, increasing);
}
else if(a > b)
decreasing = 0;
else if(a < b)
increasing = 0;
number /= 10;
}
Here, we walk through the number (by dividing by 10) until only one digit remains. We store info about the number up to this point in decreasing and increasing - a 2 means truly increasing/decreasing, a 1 means increasing/decreasing, and a 0 means not increasing/decreasing.
At each step, a is the ones digit and b is the tens. Then, we change increasing and decreasing based on a comparison between a and b.
At the end, it should be easy to turn the values of increasing and decreasing into the final answer you want.
Note: The function min returns the smaller of its 2 arguments. You should be able to write your own, or replace those lines with if statements or conditionals.
It's stupid to ask you to do loops without arrays --- but that's your teacher's fault, not yours.
That being said, I would do something like this:
char c;
while (1) {
scanf("%c", &c);
if (c == '\n') /* encountered newline (end of input) */
break;
if (c < '0' || c > '9')
break; /* do something to handle bad characters? */
c -= '0';
/*
* At this point you've got 0 <= c < 9. This is
* where you do your homework :)
*/
}
The trick here is that when you type numbers into a program, you send the buffer all at once, not one character at a time. That means the first scanf will block until the entire string (i.e. "123823" or whatever) arrives all at once, along with the newline character ( '\n' ). Then this loop parses that string at its leisure.
Edit For testing the increasing/decreasing-ness of the digits, you may think you need to store the entire string, but that's not true. Just define some additional variables to remember the important information, such as:
int largest_digit_ive_seen, smallest_digit_ive_seen, strict_increasing_thus_far;
etc. etc.
Let us suppose you have this number 23654
23654 % 10000 = 2 and 3654
3654 % 1000 = 3 and 654
654 % 100 = 6 and 54
54 % 10 = 5 and 4
4
This way you can get all the digits. Of course, you have to know if the number is greater than 10000, 1000, 100 or 10, in order to know the first divisor.
Play with sizeof to get the size of the integer, in order to avoid a huge if...else statement
EDIT:
Let us see
if (number>0) {
// Well, whe have the first and only digit
} else if (number>10) {
int first_digit = number/10;
int second_digit = number % 10;
} else if (number>100) {
int first_digit = number/100;
int second_digit = (number % 100)/10;
int third_digit = (number % 100) % 10;
} ...
and so on, I suppose
// u_i is the user input, My homework asked me to extract a long long, however, this should also be effective for a long.
int digits = 0;
long long d_base = 1;
int d_arr[20];
while (u_i / d_base > 0)
{
d_arr[digits] = (u_i - u_i / (d_base * 10) * (d_base * 10)) / d_base;
u_i -= d_arr[digits] * d_base;
d_base *= 10;
digits++;
}
EDIT: the extracted individual digit now lives in the int array d_arr. I'm not good at C, so I think the array declaration can be optimized.
Here's a working example in plain C :
#include <stdio.h>
unsigned long alePow (unsigned long int x, unsigned long int y);
int main( int argc, const char* argv[] )
{
int enter_num, temp_num, sum = 0;
int divisor, digit, count = 0;
printf("Please enter number\n");
scanf("%d", &enter_num);
temp_num = enter_num;
// Counting the number of digits in the entered integer
while (temp_num != 0)
{
temp_num = temp_num/10;
count++;
}
temp_num = enter_num;
// Extracting the digits
printf("Individual digits in the entered number are ");
do
{
divisor = (int)(alePow(10.0, --count));
digit = temp_num / divisor;
temp_num = temp_num % divisor;
printf(" %d",digit);
sum = sum + digit;
}
while(count != 0);
printf("\nSum of the digits is = %d\n",sum);
return 0;
}
unsigned long alePow(unsigned long int x, unsigned long int y) {
if (x==0) { return 0; }
if (y==0||x==1) { return 1; }
if (y==1) { return x; }
return alePow(x*x, y/2) * ((y%2==0) ? 1 : x);
}
I would suggest loop-unrolling.
int a=-1, b=-1, c=-1, d=-1, e=1, f=-1, g=-1, h=-1, i=-1; // for holding 9 digits
int count = 0; //for number of digits in the given number
if(number>0) {
i=number%10;
number/=10;
count++;
}
if(number>0) {
h=number%10;
number/=10;
count++;
}
if(number>0) {
g=number%10;
number/=10;
count++;
}
....
....
/* All the way down to the storing variable a */
Now, you know the number of digits (variable count) and they are stored in which of the variables. Now you have all digits and you can check their "decreasing", "increasing" etc with lots of if's !
I can't really think of a better soltion given all your conditions.

Resources