Remove digits from number without reversing the number - c

I got an exercise where I need to create a function that get two parameters, number (long) and digit (int) and I have to remove the digit from the number and return it.
When I do the exercise I reverse the number and in the end I reverse it again to get the original number.
I wanted to know if there is a way to do the exercise without reversing the number twice.
long myFunction(long number, int digit){
int tmp = 0;
if (digit <= 9 && digit >= 0){
while (number != 0){
if (number % 10 != digit){
tmp = (tmp + (number % 10)) * 10;
}
number = number / 10;
}
tmp = tmp / 10;
int rev = 0, remainder;
while (tmp != 0) { // Reverse an Integer
remainder = tmp % 10;
rev = rev * 10 + remainder;
tmp /= 10;
}
return rev;
}
return number;
}

A different approach could be to track the position of the digit you want to add to the result (by multiplying it by 10position). This way, you won't have to reverse the number when you're done:
long removeDigit(long number, int digit) {
long result = 0L;
long multiplier = 1L;
while (number > 0L) {
int currDigit = (int) number % 10;
if (currDigit != digit) {
result += multiplier * currDigit;
multiplier *= 10;
}
number /= 10;
}
return result;
}

Related

CS50 Credit Problem - Not working for cards with 10+ digits [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 months ago.
Improve this question
I'm new to programming and having a bit of trouble with the CS50 credit problem.
It seems to run ok until the firstCase function- this is where it's supposed to calculate the product of of every other number*2, starting from the penultimate one. It seems to return the expected result, until the user input reaches 11 digits - then it gets progressively wackier! Why might this be?
The secondCase function also seems to be adding itself to the result of firstCase (which is what you want it to do ultimately, but I wasn't aware I'd instructed it to!). Which bit of code is doing this?
I was getting INVALID (assume because of the above), so I commented out the final result, and have just been testing with printf firstSum and total.
Sorry, I know this problem has been posted many times on here, but this has got me stumped - any advice anyone can offer would be much appreciated. Thanks!
#include <cs50.h>
#include <stdio.h>
long getNumber(void);
int cardDigits(long number);
long returnDivisor(int cardLength);
long firstCase(long workingcc);
long secondCase(long workingcc);
int conditions(long total);
int cardType(int checkConditions, long divisor, int firstDigit, int secondDigit);
int main(void)
{
long number = getNumber();
int cardLength = cardDigits(number);
long divisor = returnDivisor(cardLength);
long workingcc = number;
int firstDigit = number / divisor;
int secondDigit = number / (divisor / 10);
long firstSum = firstCase(workingcc);
long total = secondCase(workingcc);
//int checkConditions = conditions(total);
//int cardResult = cardType(checkConditions, divisor, firstDigit, secondDigit);
//if (cardResult == 1){
// printf("AMEX \n");}
//else if (cardResult == 2){
// printf("MASTERCARD \n");}
//else if (cardResult == 3){
// printf("VISA \n");}
//else if (cardResult == 4){
// printf("INVALID \n");}
}
//Get card number from user
long getNumber(void){
long n;
do
{
n = get_long("card number ");
}
while (n <= 0);
return n;
}
//Obtain card length and divisor
int cardDigits(long number){
long n;
n = number;
int count = 0;
while (n > 0)
{
n = n / 10;
count++;
}
return count;
}
//Obtain divisor
long returnDivisor(int cardLength){
long divisor = 10;
for (int j = 0; j < cardLength - 2; j++)
{
divisor = divisor * 10;
}
return divisor;
}
//Obtain sum for first condition
long firstCase(long workingcc){
int sum;
workingcc = workingcc / 10;
while (workingcc !=0)
{
int lastDigit = workingcc % 10;
int timesTwo = lastDigit * 2;
sum = sum + (timesTwo % 10) + (timesTwo / 10);
workingcc = workingcc / 100;
}
return sum;
}
//Obtain sum for second condition
long secondCase(long workingcc){
int sumb;
while (workingcc > 0)
{
int lastDigit2 = workingcc % 10;
sumb = sumb + lastDigit2;
workingcc = workingcc / 100;
}
return sumb;
}
//Check total modulo 10 congruent to 0
int conditions(long total){
if (total % 10 == 0){
return 1;
}
else{
return 0;
}
}
//Check results and print card type
int cardType(int checkConditions, long divisor, int firstDigit, int secondDigit){
if (checkConditions == 1 && divisor == 15 && (secondDigit == 34 || secondDigit == 37)){
return 1;
}
else if (checkConditions == 1 && divisor == 16 && (secondDigit == 51 || secondDigit == 52 || secondDigit == 53 || secondDigit == 54 || secondDigit == 55)){
return 2;
}
else if (checkConditions == 1 && divisor == (13 | 16) && firstDigit == 4){
return 3;
}
else{
return 4;
}
}
Your first include was missing a '#' (I updated question).
firstCase(): sum is uninitialized.
secondCase(): sumb is uninitialized.
divisor == (13 | 16) means it the divisor equal to the binary OR which the same as divisor == 29.
You don't do anything with the result in main() so it may be optimized out entirely.
You can refactor those two functions as follows
long firstCase(long workingcc) {
int sum = 0;
for(workingcc /= 10; workingcc; workingcc /= 100) {
int timesTwo = (workingcc % 10) * 2;
sum += (timesTwo % 10) + (timesTwo / 10);
}
return sum;
}
long secondCase(long workingcc) {
int sumb = 0;
for(; workingcc; workingcc /= 100) {
sumb += workingcc % 10;
}
return sumb;
}
Using the American Express test credit card number of 378282246310005 firstCase() returns 27 and secondCase() returns 33. Neither now exhibit what you observed, but you need to tell us what they should be doing to verify correctness.

Validating credit cards

I'm very new to C language much less programming in general and am working through the cs50 edx course. I encountered this problem in week 1 where I'm supposed to validate credit cards given their characteristics (they're in the comments).
After hours worth of research and trials, I managed to solve it though I think it's way too long and I am 90% sure it can be shortened with loops. I added the long version that works and an iteration of it which uses loops that I just can't get to work. Any advice would help and be very much appreciated!
#include <stdio.h>
#include <cs50.h>
int main(void)
{
//user input for credit card number
long creditCard = get_long("Credit Card: ");
//initialize array for finding digits
int digit[16];
int oddDigits[8];
//separate all digits as variables in array digits[]
digit[0] = ((creditCard / 1000000000000000) % 10);
digit[1] = ((creditCard / 100000000000000) % 10);
digit[2] = ((creditCard / 10000000000000) % 10);
digit[3] = ((creditCard / 1000000000000) % 10);
digit[4] = ((creditCard / 100000000000) % 10);
digit[5] = ((creditCard / 10000000000) % 10);
digit[6] = ((creditCard / 1000000000) % 10);
digit[7] = ((creditCard / 100000000) % 10);
digit[8] = ((creditCard / 10000000) % 10);
digit[9] = ((creditCard / 1000000) % 10);
digit[10] = ((creditCard / 100000) % 10);
digit[11] = ((creditCard / 10000) % 10);
digit[12] = ((creditCard / 1000) % 10);
digit[13] = ((creditCard / 100) % 10);
digit[14] = ((creditCard / 10) % 10);
digit[15] = (creditCard % 10);
//double the value of every other digit as oddDigits[]
oddDigits[0] = digit[0] * 2;
oddDigits[1] = digit[2] * 2;
oddDigits[2] = digit[4] * 2;
oddDigits[3] = digit[6] * 2;
oddDigits[4] = digit[8] * 2;
oddDigits[5] = digit[10] * 2;
oddDigits[6] = digit[12] * 2;
oddDigits[7] = digit[14] * 2;
//the first part in finding the sum of every other digit
for (int o = 0; o < 8; o++) {
if (oddDigits[o] > 9) {
oddDigits[o] -= 9;
}
}
//part 2 of finding the sum of every other digit
int sum = 0;
for (int s = 0; s < 8; s++) {
sum += oddDigits[s];
}
//sum of everything else
for (int s2 = 1; s2 < 16; s2 += 2) {
sum += digit[s2];
}
//check if last digit is 0
int check = sum % 10;
//last part of validation
if (check != 0)
printf("INVALID\n");
//type of card
else {
if (digit[0] == 0 && digit[1] == 3 && (digit[2] == 4 || digit[2] == 7)) //15 digits starting with either 34 or 37
{
printf("AMAX\n");
}
else if (digit[0] == 5 && (digit[1] == 1 || digit[1] == 2 || digit[1] == 3 || digit[1] == 4 || digit[1] == 5)) //16 digits starting with either 51 - 54
{
printf("MASTERCARD\n");
}
else if (digit[0] == 4) //16 digits starting with 4
{
printf("VISA\n");
}
else if (digit[0] == 0 && digit[1] == 0 && digit[2] == 0 && digit[3] == 4) //13 digits starting with 4
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
}
The only part I changed is where I try to get every digit of the number using for loops and the part where I try to double every other digit... I did a test where after the loop it will print all the digits separately and it always prints 1 no matter what and I'm wondering what I'm doing wrong here...
//initialize array for finding digits
int digit[16];
int oddDigits[8];
//separate all digits as variables in array digits[]
for (int d = 0; d < 16; d++) {
for (long i = 1000000000000000; i > 9; i /= 10) {
digit[d] = ((creditCard / i) % 10);
}
}
//double the value of every other digit as oddDigits[]
for (int n = 0; n < 8; n++) {
for (int t = 0; t < 15; t += 2) {
oddDigits[n] = digit[t]*2;
}
}
While you are separating all digits as variables in array digits[], the for loop runs till.
digit[14] = ((creditCard / 10) % 10);
to fix this change it as
for (long i = 1000000000000000; i > 0; i /= 10)
{
digit[d] = ((creditCard / i) % 10);
}
ie change 9 to 0. in this way, the last iteration of the loop will run
digit[15] = ((creditCard/1) % 10);
which is same as
digit[15] = (creditCard % 10);
now see, the outer loop is running 16 times. the inner loop is also running 16 times and the inner loop is running only once per iteration of the outer loop. So one of the loops is redundant. remove the outer loop. keep the d variable as 0 and increment it by 1 after dividing the digit. i.e.
int d = 0;
//separate all digits as variables in array digits[]
for (long i = 1000000000000000; i > 9; i /= 10)
{
digit[d] = ((creditCard / i) % 10);
d++;
}
You can also do it like this
long i = 1000000000000000;
for (int d = 0; d < 16; d++)
{
digit[d] = ((creditCard / i) % 10);
i /= 10;
}
Either one will work.
Now this part //double the value of every other digit as oddDigits[]
It can also be done with 1 loop. In your code, the variable t is just double of the variable n in each step. So, you don't need the t variable too. (just replace t by 2*n)
//double the value of every other digit as oddDigits[]
for (int n = 0; n < 8; n++)
{
oddDigits[n] = digit[2*n]*2;
}

Is there a way to structure my code to add up numbers across multiple if else statements?

Right now this code takes all the products of an inputted series of digits and prints them. I want to be able to add these products together but I am struggling with how to structure it, given the if else conditions.
It needs to be able to output the total products of every 2nd digit starting from the second last and then add those products.
Any advice on how to structure this much appreciated.
// Define libraries
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
// Declare Variables
long int number;
// Defining the function and storing it in a variable
// Creating do while loop to ensure the digit amount is valid
do
{
number = get_long("Credit Card Number: ");
}
while(number < 0);
// Creating variable to store every 2nd digit of credit card number
int second_last = (number % 100)/ 10;
int fourth_last = (number % 10000)/ 1000;
int sixth_last = (number % 1000000)/ 100000;
int eighth_last = (number % 100000000)/ 10000000;
int tenth_last = (number % 10000000000)/ 1000000000;
int twelfth_last = (number % 1000000000000)/ 100000000000;
int fourteenth_last = (number % 100000000000000)/ 10000000000000;
int sixteenth_last = (number % 10000000000000000)/ 1000000000000000;
// Multiplying every 2nd digit by 2 starting from the last digit
// Multiplying every 2nd digit by 2 starting from the last digit
int second_times_two = (second_last * 2);
//finding the product of every 2nd last digit
if (second_times_two >= 10)
{
int product_second_digit = (second_times_two % 10);
int remaining_digits_second = second_times_two - 10;
int prod_second_last = (product_second_digit + 1);
printf("%i\n", prod_second_last);
}
else
{
printf("%i\n", second_times_two);
}
int fourth_times_two = (fourth_last * 2);
//finding the product of every 4th last digit
if (fourth_times_two >= 10)
{
int product_fourth_digit = (fourth_times_two % 10);
int remaining_digits_fourth = fourth_times_two - 10;
int prod_fourth_last = (product_fourth_digit + 1);
printf("%i\n", prod_fourth_last);
}
else
{
printf("%i\n", fourth_times_two);
}
int sixth_times_two = (sixth_last * 2);
//finding the product of every 6th last digit
if (sixth_times_two >= 10)
{
int product_sixth_digit = (sixth_times_two % 10);
int remaining_digits_sixth = sixth_times_two - 10;
int prod_sixth_last = (product_sixth_digit + 1);
printf("%i\n", prod_sixth_last);
}
else
{
printf("%i\n", sixth_times_two);
}
int eighth_times_two = (eighth_last * 2);
//finding the product of every eight last digit
if (eighth_times_two >= 10)
{
int product_eighth_digit = (eighth_times_two % 10);
int remaining_digits_eighth = eighth_times_two - 10;
int prod_eighth_last = (product_eighth_digit + 1);
printf("%i\n", prod_eighth_last);
}
else
{
printf("%i\n", eighth_times_two);
}
int tenth_times_two = (tenth_last * 2);
//finding the product of every tenth last digit
if (tenth_times_two >= 10)
{
int product_tenth_digit = (tenth_times_two % 10);
int remaining_digits_tenth = tenth_times_two - 10;
int prod_tenth_last = (product_tenth_digit + 1);
printf("%i\n", prod_tenth_last);
}
else
{
printf("%i\n", tenth_times_two);
}
int twelfth_times_two = (twelfth_last * 2);
//finding the product of every twelfth last digit
if (twelfth_times_two >= 10)
{
int product_twelfth_digit = (twelfth_times_two % 10);
int remaining_digits_twelfth = twelfth_times_two - 10;
int prod_twelfth_last = (product_twelfth_digit + 1);
printf("%i\n", prod_twelfth_last);
}
else
{
printf("%i\n", twelfth_times_two);
}
int fourteenth_times_two = (fourteenth_last * 2);
//finding the product of every fourtenth last digit
if (fourteenth_times_two >= 10)
{
int product_fourteenth_digit = (fourteenth_times_two % 10);
int remaining_digits_fourteenth = fourteenth_times_two - 10;
int prod_fourteenth_last = (product_fourteenth_digit + 1);
printf("%i\n", prod_fourteenth_last);
}
else
{
printf("%i\n", fourteenth_times_two);
}
int sixteenth_times_two = (sixteenth_last * 2);
//finding the product of every sixteenth last digit
if (sixteenth_times_two >= 10)
{
int product_sixteenth_digit = (sixteenth_times_two % 10);
int remaining_digits_sixteenth = sixteenth_times_two - 10;
int prod_sixteenth_last = (product_sixteenth_digit + 1);
printf("%i\n", prod_sixteenth_last);
}
else
{
printf("%i\n", sixteenth_times_two);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
}
This is a hint on how to proceed.
Make an array of 14 int to store the individual digits
Get the digits into the array using a for loop
long int curr = number;
int i =0;
while (curr >0)
{
digits[i++] = curr%10;
curr/=10;
}
Note that the above algorithm gives the digits in reverse order (i.e. digit[0] is the least significant digit)
Multiply by two the even digits as per the code above. Add and print as per algorithm above.
You can multiply all digits together using a simple for loop.

Sum of digits at Even and Odd Places in C

I need to add the digits on the even and odd places in an integer. Say, Let number = 1234567. Sum of even place digits = 2+4+6 = 12 Sum of odd place digits = 1+3+5+7 = 16
The code I currently have is:
int returnsum(int num) {
while (num) {
rem = num % 10;
sum = sum + rem;
num = num / 10;
}
while (sum) {
a = sum % 10;
arr[i] = a:
sum = sum / 10;
i++;
}
for (i = 0; a[i]; i += 2) {
summ = summ + a[i];
}
return summ;
}
void main() {
int n, m, oddSum = 0, evenSum = 0;
printf("Please insert the number for the program:");
scanf("%d", & n);
while (n != 0) {
oddSum += n % 10;
n /= 10;
evenSum += n % 10;
n /= 10;
}
printf("Sum of digits in even places:%d\n", evenSum);
printf("Sum of digits in odd places:%d\n", oddSum);
}
Here is a solution for your problem:
void main()
{
int n,m,oddSum=0,evenSum=0;
printf("Please insert the number for the program:");
scanf("%d",&n);
int flag=0;
int counter=1;
while (n!=0) {
if(counter%2==0)
{
evenSum += n % 10;
n /= 10;
}
else
{
oddSum += n % 10;
n /= 10;
}
counter++;
}
if(counter%2==0)
{
int temp=oddSum;
oddSum=evenSum;
evenSum=temp;
}
printf("Sum of digits in even places:%d\n",evenSum);
printf("Sum of digits in odd places:%d\n",oddSum);
}
Okay, let's first assume the number has an even number of digits, so that the second-last and last are at odd and even positions respectively.
Then, the last digit can be retrieved with number % 10 and the second last with (number / 10) % 10.
So, knowing that, you can simply loop over the number, adding those values and dividing by a hundred until you get a number less than ten.
If that number is zero, then your assumption about the original having an even number of digits was correct and you can exit.
If it's a non-zero (1..9), then your assumption was wrong, you should swap the even and odd sums to date then add the final digit to the odd sum.
The pseudo-code goes something like this:
def getEvenOdd (num):
even = 0
odd = 0
while num > 9:
even = even + (num % 10)
odd = odd + ((num / 10) % 10)
num = num / 100
if num > 0:
temp = even
even = odd
odd = temp
odd = odd + num
return (even,odd)
print getEvenOdd(1234567)
And the output of that would be something like (12,16).
And it's no accident that pseudo-code looks like beginner's Python, since that language is the perfect pseudo-code language, provided you don't mess about with the more complex corners of it.
Check the below code:
#include <stdio.h>
int main(void){
char p[20];
int i=0,even=0,odd=0,n;
scanf("%d",&n);
sprintf(p,"%d",n);
while(p[i] != '\0')
{
if(i%2 == 0)
odd+= (p[i] - '0');
else
even+= (p[i] - '0');
i++;
}
printf("%d\n",even);
printf("%d\n",odd);
return 0;
}
To sum every other digit, simply divide by 100 in each iteration:
int sumodd(int num) {
int sum = 0, rem;
while(num) {
rem=num%10;
sum=sum+rem;
num=num/100);
}
return sum;
}
Since we already have a function that can sum every other digit, we can re-use it:
int sumeven(int num) {
return sumodd(num/10);
}
My five cents.:)
#include <stdio.h>
typedef struct pair
{
unsigned int odd;
unsigned int even;
} pair_t;
pair_t GetSums( unsigned int x )
{
const unsigned int Base = 10;
pair_t sums = { 0u, 0u };
size_t n = 0;
do
{
if ( ++n & 1 ) sums.odd += x % Base;
else sums.even += x % Base;
} while ( x /= Base );
if ( ( n & 1 ) == 0 )
{
unsigned int tmp = sums.odd;
sums.odd = sums.even;
sums.even = tmp;
}
return sums;
}
int main(void)
{
while ( 1 )
{
unsigned int x;
pair_t sums;
printf( "\nEnter a non-negative number (0 - exit): " );
if ( scanf( "%u", &x ) != 1 || x == 0 ) break;
sums = GetSums( x );
printf( "\nSum of digits in odd positions is %u\n", sums.odd );
printf( "Sum of digits in even positions is %u\n", sums.even );
}
return 0;
}
The output might look like
Enter a non-negative number (0 - exit): 1234567
Sum of digits in odd positions is 16
Sum of digits in even positions is 12
Enter a non-negative number (0 - exit): 123456
Sum of digits in odd positions is 9
Sum of digits in even positions is 12
Enter a non-negative number (0 - exit): 0

Print integer as character digits (no arrays/printf/etc...)

I am attempting to print integers to the console in C with a few constraints, the most significant of which being that I may only write individual characters to the console as follows:
void my_char(char ch)
}
write(1, &ch, 1);
}
Other constraints include NO predefined methods (printf, log, etc). No recursion. Lastly, I may NOT create an array.
So far I have come up with a method that prints the numbers out perfectly well... backwards.
int main()
{
int i = -345320;
my_int(i);
return 0;
}
void my_int(int x)
{
char *a;
int n;
if(x < 0)
{
x = x * -1;
my_char('-');
}
while(x)
{
n = x % 10;
a = (char*)&n;
my_char(*a + 48);
x /= 10;
}
}
Are there other good ways to approach this or am I at least going in the right direction? I would ideally like to expand this to print an integer in any base I provide, but I need to start here.
I was playing with iterating a pointer over each Byte of the integer but I can't grasp how I would use those character values to re-create the integer.
Any advice is appreciated. I'd much rather receive some insight than just a code solution. I'd also love input on making it more lean.
Here's a general (ugly!) solution following your constraints. It uses the idea I gave in the comment above. It assumes 32-bit ints.
void my_int(int x) {
int n = 1000000000;
if (x == 0) {
my_char('0');
return;
}
if (x == INT_MIN) { // INT_MIN is in limits.h
my_char('-'); my_char('2'); my_char('1');
my_char('4'); my_char('7'); my_char('4');
my_char('8'); my_char('3'); my_char('6');
my_char('4'); my_char('8');
return;
}
if (x < 0) {
x *= -1;
my_char('-');
}
while (n > x) n /= 10;
while (n != 0) {
my_char(x / n % 10 + '0');
n /= 10;
}
}
This should do the trick. It prints the integer forwards.:
void my_int(int x)
{
int temp = 0;
int divFactor = 10;
if(x==0)
{
my_char('0');
return;
}
if(x < 0)
{
x = x * -1;
my_char('-');
}
temp = x;
while((temp /= 10) > 10) {divFactor *= 10;}
for(;divFactor > 0;divFactor /= 10)
{
temp = x;
temp /= divFactor;
my_char(temp + '0');
x -= divFactor * temp;
}
printf("\n done!");
}
int main()
{
int i = -1234001;
my_int(i);
return 0;
}
void my_int(int x)
{
int n;
int copy;
char digit;
// handle 0
if (!x)
{
my_char('0');
return;
}
// emit sign
if(x < 0)
{
x = x * -1;
my_char('-');
}
// count base-10 digits in x, store 10^n in n
n = 1;
copy = x/10; // shorten loop by 1 iteration
while (copy)
{
n *= 10;
copy /= 10;
}
// 'n' is now a digit selector
while (n)
{
digit = x/n;
my_char(digit + '0'); // print the most significant digit
x -= digit*n; // remove the most significant digit from x
n /= 10;
}
}

Resources