I have a 5-digit integer, say
int num = 23456;
How to find the sum of its digits?
Use the modulo operation to get the value of the least significant digit:
int num = 23456;
int total = 0;
while (num != 0) {
total += num % 10;
num /= 10;
}
If the input could be a negative number then it would be a good idea to check for that and invert the sign.
#include <stdio.h>
int main()
{
int i = 23456;
int sum = 0;
while(i)
{
sum += i % 10;
i /= 10;
}
printf("%i", sum);
return 0;
}
int sum=0;while(num){sum+=num%10;num/=10;}
Gives a negative answer if num is negative, in C99 anyway.
Is this homework?
How about this:
for(sum=0 ,num=23456;num; sum+=num %10, num/=10);
If you want a way to do it without control statements, and incredibly efficient to boot, O(1) instead of the O(n), n = digit count method:
int getSum (unsigned int val) {
static int lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // 90- 99
:
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // 23450-23459
::
};
return lookup[23456];
}
:-)
Slightly related: if you want the repeated digit sum, a nice optimization would be:
if (num%3==0) return (num%9==0) ? 9 : 3;
Followed by the rest of the code.
Actually, I answered with another (somewhat humorous) answer which used a absolutely huge array for a table lookup but, thinking back on it, it's not that bad an idea, provided you limit the table size.
The following functions trade off space for time. As with all optimisations, you should profile them yourself in the target environment.
First the (elegant) recursive version:
unsigned int getSum (unsigned int val) {
static const unsigned char lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
18, 19, 20, 21, 22, 23, 24, 25, 26, 27 // 990-999
};
return (val == 0) ? 0 : getSum (val / 1000) + lookup[val%1000];
}
It basically separates the number into three-digit groupings with fixed lookups for each possibility. This can easily handle a 64-bit unsigned value with a recursion depth of seven stack frames.
For those who don't even trust that small amount of recursion (and you should, since normal programs go that deep and more even without recursion), you could try the iterative solution:
unsigned int getSum (unsigned int val) {
static const unsigned char lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
18, 19, 20, 21, 22, 23, 24, 25, 26, 27 // 990-999
};
unsigned int tot = 0;
while (val != 0) {
tot += lookup[val%1000];
val /= 1000;
}
return tot;
}
These are probably three times faster than the one-digit-at-a-time solution, at the cost of a thousand bytes of data. If you're not adverse to using 10K or 100K, you could increase the speed to four or five times but you may want to write a program to generate the static array statement above :-)
As with all optimisation options, measure, don't guess!
I prefer the more elegant recursive solution myself but I'm also one of those types who prefer cryptic crosswords. Read into that what you will.
#include <stdio.h>
2 #include <stdlib.h>
3
4 #define BUFSIZE 20
5
6 int main(void)
7 {
8 int number = 23456;
9 char myBuf[BUFSIZE];
10 int result;
11 int i = 0;
12
13 sprintf(myBuf,"%i\0",number);
14
15 for( i = 0; i < BUFSIZE && myBuf[i] != '\0';i++)
16 {
17 result += (myBuf[i]-48);
18 }
19
20 printf("The result is %d",result);
21 return 0;
22 }
23
Another idea here using the sprintf and the ascii number representation
#include<stdio.h>
main()
{
int sum=0,n;
scanf("%d",&n);
while(n){
sum+=n%10;
n/=10;
}
printf("result=%d",sum);
}
sum is the sum of digits of number n
Related
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 months ago.
Improve this question
I am begginer,I am faced with a challenge to take few numbers and multiply the odd numbers in them to apply the lunhs alogrithm.
Ex- If user inputs 100034341341313413941391341393413.
Is there any way I can take this input and specifically filter out the numbers in the odd places and even places and add them ?
Please just show me the way or how I can get it the number in a array and approach it.The rest i'll figure out.
Thanks in advance.
The last digit is always odd so start from there. To get last digit you can use Modulo Operator (%) which gives you remainder of a division. If you divide a number by 10 you get your number's very right digit. After that divide your number by 10 (not modulo) to remove right digit. Loop this process until you get 0.
int x = 72;
int last_digit = 72 % 10; // returns 2
int x = x / 10; // its 7.2 but its an int so x will be 7
Other approaches can be found in here.
#include <stdio.h>
void getSum(int n) {
// If n is odd then the last digit
// will be odd positioned
int isOdd = (n % 2 == 1) ? 1 : 0;
// To store the respective sums
int sumOdd = 0;
int sumEven = 0;
// While there are digits left process
while (n != 0) {
// If current digit is odd positioned
if (isOdd)
sumOdd += n % 10;
// Even positioned digit
else
sumEven += n % 10;
// Invert state
isOdd = !isOdd;
// Remove last digit
n /= 10;
}
printf("Sum odd = %d\n", sumOdd);
printf("Sum even = %d\n", sumEven);
}
To calculate LUHN algorithm on a string is always far better than doing it with an int variable, as the integer has a limited amount of memory to represent the numbers normally managed in a credit card. Normally credit card numbers are 20 digits long (but they can grow up to 24 or more), while long integers reach roughly 18 digits and make it impossible to get.
In addition to what was exposed above, the LUHN algorithm can be simulated as a DFA (Deterministic Finite Automaton) that can be easily implemented with a table and a loop, as follows:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
const static char luhn_tab[][10] = {
{ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }, /* state 0, accepting state */
{ 11, 12, 13, 14, 15, 16, 17, 18, 19, 10 }, /* '' 1 */
{ 12, 13, 14, 15, 16, 17, 18, 19, 10, 11 },
{ 13, 14, 15, 16, 17, 18, 19, 10, 11, 12 },
{ 14, 15, 16, 17, 18, 19, 10, 11, 12, 13 },
{ 15, 16, 17, 18, 19, 10, 11, 12, 13, 14 }, /* '' 5 */
{ 16, 17, 18, 19, 10, 11, 12, 13, 14, 15 },
{ 17, 18, 19, 10, 11, 12, 13, 14, 15, 16 },
{ 18, 19, 10, 11, 12, 13, 14, 15, 16, 17 },
{ 19, 10, 11, 12, 13, 14, 15, 16, 17, 18 }, /* '' 9 */
{ 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }, /* state 10, accepting state */
{ 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 },
{ 2, 4, 6, 8, 0, 3, 5, 7, 9, 1 },
{ 3, 5, 7, 9, 1, 4, 6, 8, 0, 2 },
{ 4, 6, 8, 0, 2, 5, 7, 9, 1, 3 },
{ 5, 7, 9, 1, 3, 6, 8, 0, 2, 4 },
{ 6, 8, 0, 2, 4, 7, 9, 1, 3, 5 },
{ 7, 9, 1, 3, 5, 8, 0, 2, 4, 6 },
{ 8, 0, 2, 4, 6, 9, 1, 3, 5, 7 },
{ 9, 1, 3, 5, 7, 0, 2, 4, 6, 8 },
};
/* as the number of states is less than 32, we can use the bits of
* an integer to mark which states are accepting states and which aren't */
const static int accepting = (1 << 0) | (1 << 10);
int luhn_ok(char *s, size_t s_len)
{
s += s_len; /* point to the string end */
char st = 0; /* automaton state, initially zero */
while (s_len--) {
if (isdigit(*--s)) {
/* operate only on digits, skipping nondigits */
st = luhn_tab[st][*s - '0'];
}
}
/* accepting state only if final state is one of the marked
* bits in accepting */
return ((1 << st) & accepting) != 0;
} /* luhn_ok */
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++) {
printf("luhn_ok(\"%s\") == %s\n",
argv[i],
luhn_ok(argv[i],
strlen(argv[i]))
? "Good"
: "Bad");
}
} /* main */
As you see, the only difficulty lies in that I have to scan the string of digits from the rigth, instead of doing it from the left (to tie us to the odd/even position in the string) This can also be done from the left (I mean, with an automaton), but the automaton table grows up to 100 states (because we don't know if we start in an odd/even position from the left digit), instead of 20 of the table above /well, I have not minimized the table, but I think I will not get a table simpler than 100 states) Above, the state represents the expected LUHN remainder after processing the digits of the string, with 10 added if we are in an odd position or even. You will easily see that this matches the algorithm you have been given.
$ luhn "100034341341313413941391341393413" 12345678903
luhn_ok("100034341341313413941391341393413") == Bad
luhn_ok("12345678903") == Good
$ _
Note:
I have computed the 100 states table to allow computing the LUHN algorithm left to right, but finally I considered it cumbersome to add it here, as it adds no advantage to the computing (it is only interesting if you don't know in advance how long your string of digits will be, or if you are involved in a parsing algorithm that requires left to right parsing) If someone is interested, please ask for it in the comments, and I'll add it.
I'm implementing the Data Encryption Standard in C for a personal learning project and I have a seg fault that has been driving me up the wall for the past 3 days. I understand this isn't the place for "fix my code for me" type questions, but I need a second pair of eyes to look over this:
/*we must define our own modulo, as the C modulo returns unexpected results:*/
#define MOD(x, n) ((x % n + n) % n)
/*example: the 12th bit should be in the second byte so return 1 (the first byte being 0)*/
#define GET_BYTE_NUM(bit_index) (bit_index/8)
/*example: a bit index of 12 means this bit is the 4th bit of the second byte so return 4*/
#define GET_BIT_NUM(bit_index) MOD(bit_index, 8)
typedef unsigned char byte;
/*each row represents a byte, at the bit to be place in the position
* for example for the first row (first byte) we will place bits 31, 0, 1, 2, 3, 4 in
* in bit positions 0-6, respectively. The last two bits will be left blank. Since this is supposed to be a crypto implementation, static prevents this value from being accessed outside the file.*/
const static byte e_box[8][6] = { {31, 0, 1, 2, 3, 4}, {3, 4, 5, 6, 7, 8}, {7, 8, 9, 10, 11, 12}, {11, 12, 13, 14, 15, 16}, {12, 16, 17, 18, 19, 20}, {19, 20, 21, 22, 23, 24},
{23, 24, 25, 26, 27, 28}, {27, 28, 29, 30, 31, 0} }
void e(byte **four_byte_block)
{
int i, n, l = 0, four_bit_num, four_byte_num;
/*create the new byte_block and initialize all values to 0, we will have 4 spaces of bytes, so 32 bits in total*/
byte *new_byte_block = (byte*)calloc(4, sizeof(byte));
byte bit;
for(i = 0 i < 8; i++)
{
for(n = 0; n < 6; n++)
{
/*get the byte number of the bit at l*/
four_byte_num = GET_BYTE_NUM(e_box[i][n]);
/*find what index the bit at l is in its byte*/
half_bit_num = GET_BIT_NUM(e_box[i][n]);
bit = *four_byte_block[half_byte_num]; /*SEG FAULT!*/
}
}
/*finally, set four_byte_block equal to new_byte_block*/
/*four_byte_block = NULL;
* four_byte_block = new_byte_block;*/
}
I have narrowed the problem down to the line marked /SEG FAULT!/ but I can't see what the issue is. When I print the half_byte_num, I get a number that is within bounds of half_block, and when I print the values of half_block, I can confirm that those values exist.
I believe I may be doing something wrong with the pointers ie by passing **four_byte_block, (a pointer to a pointer) and it's manipulation could be causing the seg fault.
Have you tried this:
bit = (*four_byte_block)[half_byte_num];
Instead of this:
bit = *four_byte_block[half_byte_num];
Those are not the same, as an example, take the following code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
char **lines = malloc(sizeof(char *) * 8);
for (int i = 0; i < 8l; i++)
lines[i] = strdup("hey");
printf("%c\n", *lines[1]);
printf("%c\n",(*lines)[1]);
return 0;
}
The former will output h.
The latter will output e.
This is because of the operators precedence, [] will be evalued before *, thus if you want to go to the nth index of *foo, you need to type (*foo)[n].
I have implemented 0-1 knapsack. "DP" is the 1D table that holds maximum profits. "capacity" is the maximum capacity, "n" is the number of elements. At the end it holds the last row of 2D classic approach in "DP". But i can't figure out how to get which elements are used with just looking at the 1D array.
DP = (int*)calloc(capacity + 1, sizeof(int));
used = (int*)calloc(n, sizeof(int));
for (i = 0; i < n; i++) {
for (j = capacity; j > 0; j--) {
if (weight[i] <= j && DP[j] < DP[j - weight[i]] + profit[i]) {
DP[j] = DP[j - weight[i]] + profit[i];
used[i] = 1;
}
}
}
// for example
// int profit[] = { 7, 16, 13, 8, 1, 11, 14, 11, 12, 7, 6, 10, 1, 1, 11, 12}
// int weight[] = { 6, 2, 7, 2, 1, 2, 5, 4, 12, 16, 1, 4, 10, 12, 12, 2}
// results DP = {0, 6, 16, 22, 28, 34, 39, 45, 47}
// total profit of used elements: 72 <- it should be 47
// total weight of used elements: 20 <- it should be lesser than 8(the capacity)
This is my code initializing the array:
#include <stdio.h>
int main (void) {
int x, n;
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int *array = {2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 25, 29, 30, 34, 35, 38};
n = sizeof(array) / sizeof(int);
for (x=0; x<n; x++) {
printf("%i: %i - ", x, array[x]);
}
printf("\nArray's length: %i", n);
return 0;
}
I'm not understanding why this simple code shows this message:
Runtime error
Thanks in advance.
Change this:int *array = to this: int array[] =. Ideone link: https://ideone.com/ULH7i6 . See this too: How to initialize all members of an array to the same value?
What did you have in mind when you declared the following line?
int *array = {2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 25, 29, 30, 34, 35, 38};
What comes to mind when I see something like this you're trying to work with an array using pointer arithmetic, which makes for a lot of fun interview questions (and just cool in general :P ). On the other hand you might just be used to being able to create arrays using array literals.
Below is something that talks about the different types of arrays you might be trying to work with. I know you picked an answer but this might be useful to you if you were trying to accomplish something else.
C pointer to array/array of pointers disambiguation
Your array declaration is not correct.... just edit your declaration to
int *array[] = {2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 25, 29, 30, 34, 35, 38};
here the correction code!
#include <stdio.h>
int main (void) {
int x, n;
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int *array[] = {2, 4, 6, 9, 11, 13, 15, 17, 19, 21, 25, 29, 30, 34, 35, 38};
n =sizeof(array) / sizeof(int);
for (x=0; x<n; x++) {
printf("%i: %i - ",x,array[x]);
}
printf("\nArray's length: %i", n);
return 0;
}
I have one strange problem while using fwrite() in C.After editing of file with integers, i get zero ("0") before my last element which added by fwrite().My exercise is to divide integers in file on groups which are consisted of 10 elements or less.
For example, i have :
{2, 3, 9, 4, 6, 7, 5, 87, 65,12, 45, 2, 3, 4, 5, 6, 7, 8, 9}
after editing i need :
{2, 3, 9, 4, 6, 7, 5, 87, 65, 12, 87, 45, 2, 3, 4, 5, 6, 7, 8, 9, 45 };
With code below I get:
{2, 3, 9, 4, 6, 7, 5, 87, 65, 12, 87, 45, 2, 3, 4, 5, 6, 7, 8, 9, 0, 45 };
In the process of step-by-step debugging fwrite() works only two times, it wites 87 after first ten elements, and 45 after remained.Zero wasn`t writed by fwrite().Is that so?From where it comes finally?
My code:
while (!feof(fp)) {
fread(&elems[k], sizeof(int), 1, fp);
fwrite(&elems[k], sizeof(int), 1, hp);
++k;
if (k == 10 || feof(fp)){
for (i = 0; i < 10; ++i){
if (elems[i] > max_number){
max_number = elems[i];
}
}
fwrite(&max_number, sizeof(int), 1, hp);
for (i = 0; i < 10; ++i){
elems[i] = 0;
}
max_number = INT_MIN;
k = 0;
}
}
Thank for answers!
Using feof will result in reading an extra item.
Must check for errors from fwrite and fread calls.
One possible error is the EOF error.
If fread returns 0 items read the value will be left at whatever it was before. Probably 0. Which is probably where your extra 0 comes from.