How to get every digit from a number in C? - c

I have these variables:
int dividend;
 int divider;
And I have the function :
Divisibility7 (int num);
Those two variables will be at the main function, and the user will be asked to enter the dividend and divider, but in case the user enter the divider 7, then, the function above will be called.
The problem is that I have to follow specific criteria to do this. So let's say the user will enter with the dividend 7203. This happen :
I. Get the last digit of the number.
Last digit: 3
Ii. Multiply the last digit by 2
3 x 2 = 6
Iii. Get the value of the initial number, without the last digit.
720
Iv. Subtract the initial value without the last digit from the multiplication result.
fabs (720 - 6) = 714
V. Repeat the process until the result is a value less than or equal to 70
Vi. Compare the result with the table of contents (0, 7, 14, 21, 28, 35, 42, 49, 54, 63, 70) for
Determine whether or not the number is divisible by 7
Code :
int res;
int x;
int y;
int Divisibility7(int num) {
int res;
int x;
int y;
int z;
while(num > 70) {
x = num % 10; // get the last digit from the number
y = x * 2; // multiply the last digit by 2;
z = num/10; // get the first digits from the number
fabs(z - y); // subtract the first digits with the last digits;
}
}
In the part of the while, the final fabs(z-y) returns what I want, to be the first digits subtracting the last number, but the problem is that the while stop there, I have to do something to make this while go till 70 or less.
PS : I need to check if the final number from the iterations, it's a number multiplied by 7, how can I do that ? And I can't use mod for this.

You have not changed num in your while loop . Also you do no return the value . Hope the following code will be ok for you .
int Divisibility7(int num) {
int res,x,y,z;
while(num > 70) {
x = num % 10; // get the last digit from the number
y = x * 2; // multiply the last digit by 2;
z = num/10; // get the first digits from the number
num = abs(z - y); // subtract the first digits with the last digits;
}
if(num == 0 || num == 7 || num == 14 || num == 21 || num == 28 || num == 35 || num == 42 || num == 49 || num == 54 || num == 63 || num == 70) {
return 1;
}
else {
return 0;
}
}

Not sure, but I think this is what are you trying to do:
int main (void)
{
int number, lastDigitMultiplied;
scanf("%d", &number);
while(number > 70){
//get the last digit and multiply it by 2
lastDigitMultiplied = (number % 10) * 2;
//subtract the initial value without the last digit from the multiplication result.
number = number / 10 - lastDigitMultiplied;
}
if(abs(number) % 7 == 0)
printf("The result is %d and it is a multiple of 7", number);
else
printf("The result is %d and it is not a multiple of 7", number);
return 0;
}

for divisibility against 7, if you have a positive large bigint already formatted as a string, don't waste time with the regular method doing it 1 digit at a time.
powers of 10, mod 7, repeats every 6 rounds :
10^1 % 7 = 3 10^7 % 7 = 3 10^13 % 7 = 3
10^2 % 7 = 2 10^8 % 7 = 2 10^14 % 7 = 2
10^3 % 7 = 6 10^9 % 7 = 6 10^15 % 7 = 6
10^4 % 7 = 4 10^10 % 7 = 4 10^16 % 7 = 4
10^5 % 7 = 5 10^11 % 7 = 5 10^17 % 7 = 5
10^6 % 7 = 1 10^12 % 7 = 1 10^18 % 7 = 1
meaning, the effects of the digits mod 7 stay identical as long as they're in chunks of 6 digits at a time.
the largest multiple of 6-digits supported by double precision FP to full integer precision would be 12-digits at a time.
So the way to do it is to right-align the digits by padding leading edge zeros to ensure string length is a multiple of 12. Then simply add the digits onto each other, performing a single mod % 7 operation once every 9000 or so rounds of the addition loop
—- (that's when you run up against 2^53 limit; 9007 rounds if u wanna be pedantic about it)
example :
x = 71400535477047763120175175402859619447790
02233464423375355339031113233806609150957
x % 7 = 4
now try summing up chunks of 12 :
007140053547704776312017517540285961944779
002233464423375355339031113233806609150957
007140053547 7140053547
704776312017 711916365564
517540285961 1229456651525
944779002233 2174235653758
464423375355 2638659029113
339031113233 2977690142346
806609150957 3784299293303
----------------------------
3784299293303 % 7 = 4
it works exactly the same for any multiples of 6 : e.g. 6, 18, 24, and 30 --
00714005354770477631201751754
02859619447790022334644233753
55339031113233806609150957
312017 312017
517540 829557
285961 1115518
944779 2060297
002233 2062530
464423 2526953
375355 2902308
339031 3241339
113233 3354572
806609 4161181
150957 4312138
007140 4319278
053547 4372825
704776 5077601
----- -------
_ 5077601 % 7 = 4
00000000714005354770477631201
75175402859619447790022334644
23375355339031113233806609150957
464423375355339031 464423375355339031
113233806609150957 577657181964489988
000000007140053547 577657189104543535
704776312017517540 1282433501122061075
285961944779002233 1568395445901063308
---------------------------------------
1568395445901063308 % 7 = 4
00000000000000714005354770477
63120175175402859619447790022
33464423375355339031113233806
609150957
339031113233806609150957 339031113233806609150957
000000000000007140053547 339031113233813749204504
704776312017517540285961 1043807425251331289490465
944779002233464423375355 1988586427484795712865820
---------------------------------------------------
1988586427484795712865820 % 7 = 4
000000007140053547704776312017517
540285961944779002233464423375355
339031113233806609150957
000000007140053547704776312017 7140053547704776312017
517540285961944779002233464423 517540293101998326707009776440
375355339031113233806609150957 892895632133111560513618927397
892895632133111560513618927397 % 7 = 4

Related

Explain the algorithm and check whether the number is a prime number or not?

I'm understand only the code, but not it's core concept anyone explain about its flow chart and Algorithm
why we use i<=n/2 in this code is there any way to use i<=n
#include <stdio.h>
int main() {
int n, i, flag = 0;
printf("Enter a positive integer: ");
scanf("%d", &n);
for (i = 2; i <= n / 2; ++i) {
// condition for non-prime
if (n % i == 0) {
flag = 1;
break;
}
}
if (n == 1) {
printf("1 is neither prime nor composite.");
}
else {
if (flag == 0)
printf("%d is a prime number.", n);
else
printf("%d is not a prime number.", n);
}
return 0;
}
Suppose n is composite. Then n=ab for some integers a,b>1. Your first loop checks if a or b is an integer in the range [2, n/2]. If that loop never finds a factorization like that, it must be that one of the factors (if it exists) is greater than n/2. If it is greater than n/2, the other factor must be less than 2. The only such factorization is n=1n, in which case n is in fact a prime. Thus it suffices to check only factors up to n/2.
PS: I deliberately don't specify what I mean when n is odd. That's left as an exercise for you to fill in.
PPS: You can easily do a lot better than stopping at n/2. Hint: What happens when both factors are the same?
In the code you are using i <= n / 2 because for any numbers, you can't divide itself by another number greater than its half.
Let's take 29 for example (and use int, so not floating part).
29 / 2 = 14
29 / 3 = 9
29 / 4 = 7
29 / 5 = 5
...
29 / 14 = 2
29 / 15 = 1
29 / 16 = 1
...
Here, you see that after 14 (the half of 29), all the results are 1.
If you wish to, you can even use this formula n > i * i. Let me explain with this example. Here, we should stop at i = 5 because 29 < 6 * 6
29 / 2 = 14
29 / 3 = 9
29 / 4 = 7
29 / 5 = 5
===== END HERE (but let's continue to see what happens) =====
29 / 6 = 4
29 / 7 = 4
29 / 8 = 3
...
You can see that after 5, the results become smaller than the index, so you are just recalculating something that you have already calculated. It avoids timeouts on big numbers.

Count ones in a segment (binary)

There is a problem which i am working on it right now and it's as the following :
there are two numbers x1 and x2 and x2 > x1.
for example x1 = 5; and x2 = 10;
and I must find the sum of ones between x1 and x2 in binary representations.
5 = 101 => 2 ones
6 = 110 => 2 ones
7 = 111 => 3 ones
8 = 1000 => 1 one
9 = 1001 => 2 ones
10= 1010 => 2 ones
so the sum will be
sum = 2 + 2 + 3 + 1 + 2 + 2 = 12 ones;
so I have managed to make a code without even transfer the numbers to binary and wasting execution time.
I noticed that the numbers of ones in every 2^n with n >= 1 is 1
Ex : 2^1 => num of ones is 1
2^2 => 1 2^15 => 1
you can test it here if you want: https://www.rapidtables.com/convert/number/decimal-to-binary.html?x=191
and between each 2^n and 2^(n+1) there are Consecutive numbers as you will see in this example :
num number of ones
2^4 = 16 1
17 2
18 2
19 3
20 2
21 3
22 3
23 4
24 2
25 3
26 3
27 4
28 3
29 4
30 4
31 5
2^5 = 32 1
so I write a code that can find how many ones between 2^n and 2^(n+1)
int t; ////turns
int bin = 1; //// numbers of ones in the binary format ,,, and 1 for 2^5
int n1 = 32; //// 2^5 this is just for clarification
int n2 = 64; //// 2^6
int *keep = malloc(sizeof(int) * (n2 - n1); ///this is to keep numbers because
/// i'll need it later in my consecutive numbers
int i = 0;
int a = 0;
n1 = 33 //// I'll start from 33 cause "bin" of 32 is "1";
while (n1 < n2) /// try to understand it now by yourself
{
t = 0;
while (t <= 3)
{
if (t == 0 || t == 2)
bin = bin + 1;
else if (t == 1)
bin = bin;
else if (t == 3)
{
bin = keep[i];
i++;
}
keep[a] = bin;
a++;
t++;
}
n1++;
}
anyway as you see I am close to solve the problem but they give me huge numbers and I must find the ones between them, unfortunately I have tried a lot of methods to calculate the "sum" using this above code and I ended up with time execution problem.
Ex: 1, 1000000000 the numbers of ones is >>> 14846928141
so can you give me a little hint what to do next, thanks in advance.
I'm doing this for CodeWar challenge: https://www.codewars.com/kata/596d34df24a04ee1e3000a25/train/c
You can solve this problem by computing the number of bits in the range 1 to n and use a simple subtraction for any subrange:
#include <stdio.h>
#include <stdlib.h>
/* compute the number of bits set in all numbers between 0 and n excluded */
unsigned long long bitpop(unsigned long long n) {
unsigned long long count = 0, p = 1;
while (p < n) {
p += p;
/* half the numbers in complete slices of p values have the n-th bit set */
count += n / p * p / 2;
if (n % p >= p / 2) {
/* all the numbers above p / 2 in the last partial slice have it */
count += n % p - p / 2;
}
}
return count;
}
int main(int argc, char *argv[]) {
unsigned long long from = 1000, to = 2000;
if (argc > 1) {
to = from = strtoull(argv[1], NULL, 0);
if (argc > 2) {
to = strtoull(argv[1], NULL, 0);
}
}
printf("bitpop from %llu to %llu: %llu\n", from, to, bitpop(to + 1) - bitpop(from));
return 0;
}
Here is a proposal for a speedup:
Find smallest y1 such that y1 >= x1 and that y1 is a power of 2
Find largest y2 such that y2 <= x2 and that y2 is a power of 2
Find p1 and p2 such that 2^p1=y1 and 2^p2=y2
Calculate the amount of 1:s between y1 and y2
Deal with x1 to y1 and y2 to x2 separately
Sum the results from 4 and 5
Let's focus on step 4. Let f(n) be the sum of ones up to (2^n)-1. We can quickly realize that f(n) = 2*f(n-1) + 2^(n-1) and that f(1)=1. This can be even further refined so that you don't have to deal with recursive calls, but I highly doubt it will be of any importance. Anyway, f(n) = n*2^(n-1)
To get the result between y1 and y2, just use f(p2)-f(p1)
For step 5, you can likely use a modified version of step 4.
EDIT:
Maybe I was to quick to say "quickly realize". Here is a way to understand it. The amounts of ones up to 2¹-1 is easy to see. The only two binary numbers below 2¹ are 0 and 1. To get the number of ones up to 2² we take the numbers below 2¹ and make a column:
0
1
Clone it:
0
1
0
1
And put 0:s before the first half and 1:s before the second half:
00
01
10
11
To get 2³ we do the same. Clone it:
00
01
10
11
00
01
10
11
And add 0 and 1:
000
001
010
011
100
101
110
111
Now it should be easy to see why f(n) = 2*f(n-1) + 2^(n-1). The cloning gives 2f(n-1) and adding the 0:s and 1:s gives 2^(n-1). If 2^(n-1) is hard to understand, remember that 2^(n-1)=(2^n)/2. In each step we have 2^n rows and half of them get an extra 1.
EDIT2:
When I looked at these columns, I got an idea for how to do step 5. Let's say that you want to find the amounts of 1:s from 10 to 15. Binary table for this would be:
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
15: 1111
Look at the interval 12-15. The last two digits in binary is a copy of the corresponding table for 0-3. That could be utilized, but I leave that to you.
EDIT 3:
This was a fun problem. I wrote some python code that does this. I get some problems with too many recursive calls, but that could be solved pretty easily, and it should not be too complicated to convert this to C:
def f(n):
return n*2**(n-1)
def numberOfOnes(x):
if(x==0):
return 0
p = floor(log(x,2))
a = f(p)
b = numberOfOnes(x-2**p)
c = x - 2**p +1
return a+b+c
I made an image so that you easier can understand what a, b and c does in the function numberOfOnes if we call it with numberOfOnes(12):
I have finally converted it to C. Of course I have used some code I found here on Stack overflow. I borrowed code for integer versions of log2 and pow, and made some small modifications.
This code is probably possible to optimize further, but it is not necessary. It is lighting fast, and I was not able to measure it's performance.
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <stdint.h>
#include <inttypes.h>
typedef uint64_t T;
// https://stackoverflow.com/a/11398748/6699433
const int tab64[64] = {
63, 0, 58, 1, 59, 47, 53, 2,
60, 39, 48, 27, 54, 33, 42, 3,
61, 51, 37, 40, 49, 18, 28, 20,
55, 30, 34, 11, 43, 14, 22, 4,
62, 57, 46, 52, 38, 26, 32, 41,
50, 36, 17, 19, 29, 10, 13, 21,
56, 45, 25, 31, 35, 16, 9, 12,
44, 24, 15, 8, 23, 7, 6, 5};
T log2_64 (T value) {
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value |= value >> 32;
return tab64[((T)((value - (value >> 1))*0x07EDD5E59A4E28C2)) >> 58];
}
// https://stackoverflow.com/a/101613/6699433
T ipow(T base, T exp) {
T result = 1;
for (;;) {
if (exp & 1) result *= base;
exp >>= 1;
if (!exp) break;
base *= base;
}
return result;
}
T f(T n) { return ipow(2,n-1)*n; }
T numberOfOnes(T x) {
if(x==0) return 0;
T p = floor(log2(x));
T a = f(p);
T e = ipow(2,p);
T b = numberOfOnes(x-e);
T c = x - e + 1;
return a+b+c;
}
void test(T u, T v) {
assert(numberOfOnes(u) == v);
}
int main() {
// Sanity checks
test(0,0);
test(1,1);
test(2,2);
test(3,4);
test(4,5);
test(5,7);
test(6,9);
// Test case provided in question
test(1000000000,14846928141);
}
int x1 = 5;
int x2 = 10;
int i=0;
int looper = 0;
unsigned long long ones_count = 0;
for(i=x1; i<=x2; i++){
looper = i;
while(looper){
if(looper & 0x01){
ones_count++;
}
looper >>= 1;
}
}
printf("ones_count is %llu\n", ones_count);
return 0;
OUTPUT: ones_count is 12
Here is a way to count every single bit for every value in between the two values. The shift/mask will be faster than your arithmetic operators most likely, but will still probably time out. You need a clever algorithm like the other answer suggests i think, but heres the stupid brute force way :)
This was my solution to the problem:
** = exponentiation
/ = whole number division
Consider the numbers from 1 to 16:
00001
00010
00011
00100
00101
00110
00111
01000
01001
01010
01011
01100
01101
01110
01111
10000
If you pay attention to each column, you'll notice a pattern. The bit at column index i (0,1,2 ...) from the right runs through a cycle of length 2**(i+1), that is every 2**(i+1) rows, the pattern in column i repeats itself. Notice also that the first cycle starts at the first occurrence of a 1 in a given column. The number of ones in a pattern is half of the patterns length.
Example:
i pattern
0 10
1 1100
2 11110000
3 1111111100000000
...
So, given the task of summing all ones up to n, we have to keep track of how many times each pattern repeats itself and also if a pattern fails to complete itself.
Solution:
Let x be the biggest exponent of a binary number n and let s be the sum of all ones up to n. Then, for i = (0, 1, 2, ... , x) add (n / 2**(i+1)*(2**i) to s. If the remainder is bigger than 2**i, add 2**i to s, else add the remainder. Then subtract 2**i from n and repeat the process.
Example:
n = 7 -> x = 2
(7 / 2**1)*(2**0) = 3
7 % 2**1 = 1 !> 2**0
s = 1 + 3 (4)
n = n - 2**0 (6)
(6 / 2**2)*(2**1) = 2
6 % 2**2 = 2 !> 2**1
s = s + 2 + 2 (8)
n = n - 2**1 (4)
(4 / 2**3)*(2**2) = 0
4 % 2**3 = 4 !> 2**2
s = s + 4 (12)
n = n - 2**2 (0)
s = 12
Maybe not the best explanation or the most beautiful solution, but it works fine.
In python:
def cnt_bin(n):
bits = n.bit_length()
s = 0
for i in range(bits):
s += (n // 2**(i+1))*2**i
if n % 2**(i+1) > 2**i:
s += 2**i
else:
s += (n % 2**(i+1))
n -= 2**i
return s
Then, for a range [a, b] you just compute cnt_bin(b) - cnt_bin(a-1)

How to make sense of modulo in c

i am not understanding this modulo in c languge.
For example:
#include <stdio.h>
#include<math.h>
int main()
{
int my_input[] = {23, 22, 21, 20, 19, 18};
int n, mod;
int nbr_items = sizeof(my_input) / sizeof(my_input[0]);
for (n = 0; n < nbr_items; n++)
{
mod = my_input[n] % 4;
printf("%d modulo %d --> %d\n", my_input[n], 4, mod);
}
}
Gives:
23 modulo 4 --> 3
22 modulo 4 --> 2
21 modulo 4 --> 1
20 modulo 4 --> 0
19 modulo 4 --> 3
18 modulo 4 --> 2
I would have expected a number that i can make sense of.
Essentially i am trying to test if a number is divisible by 4.
The modulo operator in C will give the remainder that is left over when one number is divided by another. For example, 23 % 4 will result in 3 since 23 is not evenly divisible by 4, and a remainder of 3 is left over.
If you want to output whether or not a number is divisible by 4, you need to output something other than just the mod result. Essentially, if mod = 0 than you know that one number is divisible by another.
If you want to output whether or not the number is divisible by 4, I would suggest creating a new character that is set to "y" (yes) or "n" (no) depending on the result of the mod operation. Below is one possible implementation to generate a more meaningful output:
#include <stdio.h>
#include <ctype.h>
#include <math.h>
int main()
{
int my_input[] = {23, 22, 21, 20, 19, 18};
int n, mod;
char is_divisible;
int nbr_items = sizeof(my_input) / sizeof(my_input[0]);
for (n = 0; n < nbr_items; n++)
{
mod = my_input[n] % 4;
is_divisible = (mod == 0) ? 'y' : 'n';
printf("%d modulo %d --> %c\n", my_input[n], 4, is_divisible);
}
}
This will give the following:
23 modulo 4 --> n
22 modulo 4 --> n
21 modulo 4 --> n
20 modulo 4 --> y
19 modulo 4 --> n
18 modulo 4 --> n
I'm sure we know the basic division equation from high school math
dividend = divisor*quotient + remainder
Now:
1. The "/" operator gives us the quotient.
2. The "%" operator gives us the remainder
example:
say a = 23, b = 4
a / b = 23 / 4 = 5
a % b = 23 % 4 = 3
23 = 4*5 + 3
Here 4 is the quotient and 3 is the remainder.
If a number is perfectly divisible by a divisor, then remainder is zero.
So:
20/4 = 5 (quotient)
20%4 = 0 (remainder)
To test if a no if divisible by 4, the check should be something like if (num % 4 == 0).
Hope this helps!

We are given a number lets say m. We have to distribute the number into n parts

Lets says I have a number m = 9. I want to divide it into n=5 parts like given below:
As m>n, each part will get at least 1.
First give 1 to all 5 parts
part0: 1,
part1: 1,
part2: 1,
part3: 1,
part4: 1
Now for the remaining (9 - 5 = 4) divide again starting from 1st. final allocation looks like:
part0: 2
part1: 2
part2: 2
part3: 2
part4: 1
algo:
take an array arr[n]={0}.
x=0
while(m) {
arr[x]+=1;
m--;
x=(x+1)%n;
}
My question is I don't want to run this loop to divide n into m parts. Mathematically, how can I know the value allocated to a part directly. i.e part0: 2 for above example.
Integer division gets you the "base" size of all parts: 9 / 5 == 1.
Modulo gives you the remainder, 9 % 5 == 4. This means you should add 1 to the first 4 parts.
int partCount = 5;
int number = 9;
int base = number / partCount;
int remain = number % partCount;
for (int i=0; i<partCount; i++) {
part[i] = base;
if (i < remain) part[i]++;
}
The algorithm might be clearer if you use larger numbers. E.g. 31 in 7 parts:
31 / 7 == 4 - so we have 7 parts of 4 each, (== 28) plus the remainder:
31 % 7 == 3 - give the first 3 parts 1 more each to make 31 total.
for (i=0; i<n; i++) {
arr[i] = m/n + (m%n < i ? 1 : 0);
}

How to check if a int var contains a specific number

How to check if a int var contains a specific number
I cant find a solution for this. For example: i need to check if the int 457 contains the number 5 somewhere.
Thanks for your help ;)
457 % 10 = 7 *
457 / 10 = 45
45 % 10 = 5 *
45 / 10 = 4
4 % 10 = 4 *
4 / 10 = 0 done
Get it?
Here's a C implementation of the algorithm that my answer implies. It will find any digit in any integer. It is essentially the exact same as Shakti Singh's answer except that it works for negative integers and stops as soon as the digit is found...
const int NUMBER = 457; // This can be any integer
const int DIGIT_TO_FIND = 5; // This can be any digit
int thisNumber = NUMBER >= 0 ? NUMBER : -NUMBER; // ?: => Conditional Operator
int thisDigit;
while (thisNumber != 0)
{
thisDigit = thisNumber % 10; // Always equal to the last digit of thisNumber
thisNumber = thisNumber / 10; // Always equal to thisNumber with the last digit
// chopped off, or 0 if thisNumber is less than 10
if (thisDigit == DIGIT_TO_FIND)
{
printf("%d contains digit %d", NUMBER, DIGIT_TO_FIND);
break;
}
}
Convert it to a string and check if the string contains the character '5'.
int i=457, n=0;
while (i>0)
{
n=i%10;
i=i/10;
if (n == 5)
{
printf("5 is there in the number %d",i);
}
}

Resources