Example:
When the division is applied as a whole, the result is,
The summation formula is given by,
The above can be easily calculated in O(1), using the rules of summation.
But when it is applied to each term individually(truncating after the decimal point in the quotient),
=0+1+1+2+3+3+4+5=19. [using normal int/int division in C]
The above method requires O(N) as rules of summation can NOT be applied.
I understand the above is due to loss of precision is more when the division is applied to each term rather than at the last. But this is exacly what I need.[In the above example, 19 is the required solution and not 21]
Is there a formula that would serve as a shortcut for applying division individually to each term, similar to summation?
So, you get:
0 + (1+1+2) + (3+3+4) + 5
Let's multiply this by 3:
0 + (3+3+6) + (9+9+12) + 15
And compare it with the numerator of (1+...+15)/3:
1 + (3+5+7) + (9+11+13) + 15
You can clearly see that the sum you're seeking is losing 3 every 3 terms to the numerator or 1 in every term on average. And it doesn't matter how we group terms into triples:
(0+3+3) + (6+9+9) + 12+15
(1+3+5) + (7+9+11) + 13+15
or even
0+3 + (3+6+9) + (9+12+15)
1+3 + (5+7+9) + (11+13+15)
So your sum*3 is less than the numerator of (1+...+15)/3 by about the number of terms.
And the numerator can be calculated using the formula for the sum of the arithmetic progression: n2, where n is the number of terms in the sum:
1+3+5+7+9+11+13+15 = 28 = 64
Now you subtract 8 from 64, get 56 and divide it by 3, getting 18.6(6). The number isn't equal to 19 because n (the number of terms) wasn't a multiple of 3.
So, the final formula isn't exactly (n2-n)/3, but differs in value at most by 1 from the correct one.
In fact, it's:
(n*n-n+1)/3 rounded down or calculated using integer division.
Plugging the number(s) into it we get:
(8*8-8+1)/3 = 57/3 = 19
Short answer: Yes there is such a formula.
Long answer (as I guess you want the formula):
How to get it: You already realized that the difference between the summation formula and the sum of the int devision came from the rounding of the int division at each summand.
Make a table with the rows:
First row, the result of each summand, when you divide with full precision.
Second row, the reuslt of each summand, when you perform integer division.
And third row, the difference of both.
Now you should realize the pattern, its always 1/3, 0, 2/3.
That came from the division by 3, you could proof that formal if you want (e.g. induction).
So in the end your formula is: (n^2)/3 - (n/3)
the n*n/3 is the regular summation formula, and as for all full 3 summands 1 is lost we subtract n/3.
The result is going to be
1+1 + 2 + 3+3 + 4 + 5+5 + 6 + 7+7 + 8 + 9+9 + 10 + ...
in other words all odd numbers appear twice and all even numbers once. The sum of first n natural numbers is n*(n+1)/2 so the sum of first n even natural numbers is twice that and the sum of first n odd numbers is instead n*n.
I think you now have all pieces to get the result you need...
The sums you need are, for increasing ns:
1, 2, 4, 7, 10, 14, 19, 24, 30, 36 ...
Plug these into the The On-Line Encyclopedia of Integer Sequences™ (OEIS™) and you get A007980 as the series that fits your requirements. It is calculated as a(n)=ceil((n+1)*(n+2)/3).
This makes a(0) = 1, a(1) = 2, a(6) = 19, meaning the index is offset by 2: sum(1,8) = a(8-2).
Σ((2i+1)/3) where i =0 to n-1 and Σ((2i+1)/3) = n*n/3
#include <stdio.h>
typedef struct fraction {
int n;//numerator
int d;//denominator
} Fraction;
int gcd(int x, int y){
x = (x < 0)? -x : x;
y = (y < 0)? -y : y;
while(y){
int wk;
wk = x % y;
x = y;
y = wk;
}
return x;
}
Fraction rcd(Fraction x){
int gcm;
gcm = gcd(x.n, x.d);
x.n /= gcm;
x.d /= gcm;
return x;
}
Fraction add(Fraction x, Fraction y){
x.n = y.d*x.n + x.d*y.n;
x.d = x.d*y.d;
return rcd(x);
}
int main(void){
Fraction sum = {0,1};
int n;
for(n=1;n<=8;++n){
Fraction x = { 2*n-1, 3 };
sum = add(sum, x);
}
printf("%d/%d=",sum.n,sum.d);
printf("%d",sum.n/sum.d);
return 0;
}
Related
Problem Statement:
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.
Example 1:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
Example 2:
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
Using the following knowledge about squares (given below) we can implement the following solution.
A natural number is...
... a square if and only if each prime factor occurs to an even power in the number's prime factorization.
... a sum of two squares if and only if each prime factor that's 3 modulo 4 occurs to an even power in the number's prime factorization.
... a sum of three squares if and only if it's not of the form 4a(8b+7) with integers a and b.
... a sum of four squares. Period. No condition. You never need more than four.
int numSquares(int n) {
while (n % 4 == 0)
n /= 4;
if (n % 8 == 7)
return 4;
for (int a=0; a*a<=n; ++a) {
int b = sqrt(n - a*a);
if (a*a + b*b == n)
return 1 + !!a;
}
return 3;
}
Question:
Can someone help me understand what exactly are we trying to achieve in following for loop?
I'm a little lost here.
for (int a=0; a*a<=n; ++a) {
int b = sqrt(n - a*a);
if (a*a + b*b == n)
return 1 + !!a;
}
The loop is trying to find two squares that sum to n.
Rather than trying every combination of numbers to see if we can square them and they add up to n, we just loop through the possibilities for one of the numbers -- this is a. We square that with a*a, and subtract that from n. We then get the integer part of the square root of this difference, and this is b. If a2+b2 adds up to n, this is the pair of squares that we're looking for.
We need to calculate the sum of the squares in case n - a*a wasn't a perfect square. In that case its square root will have a fraction in it, which will be lost when we convert it to an integer. In other words, testing a*a+b*b == n allows us to determine whether the square root was an integer.
Question asked in oracle interview.For example,if my input is 6, then
5+1=6 Ans:2
4+2=6 Ans:2
3+2+1=6 Ans:3
So, the final answer should be 3.(i.e 3,2,1 are needed to get sum 6)
Note:Repetition of number isn't allowed (i.e 1+1+1+1+1+1=6)
I solved it using recursion but interviewer wasn't satisfied. Is Dynamic Programming possible?
The minimum sum of x numbers is
So just find x that satisfies the inequality:
Here's the code:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int x = 1;
while ((x+1)*x/2 <= n) x++;
x--; // now (x+1)*x/2 > n , so x is too large
printf("%d\n", x);
return 0;
}
You can use binary search if n is very large.
I was about to post the answer but #Cruise Liu beat me to it. Ill try explaining it a bit .
Its a type of integer partitioning but you dont need to generate the elements since you're only interested in the 'number of elements'. i.e. the final answer 3 and not {1, 2, 3}
Given a number N, you have another restriction that numbers cannot repeat.
Hence the best case would be if N is actually a number say 1, 3, 6, 10, 15
i.e. f(x) = x * (x + 1) / 2.
For example, take 6. f(x) = 6 exists. specifically f(3) = 6 . Thus you get the answer 3.
What this means is that if there is an integer X that exists for f(x) = N, then there is a set of numbers 1, 2, 3 ... x that when added up give N. And this is the maximum number possible (without repitition).
However, there are cases in f(x) = N where x is not an integer.
f(x) = x * (x + 1 ) / 2 = N
i.e. x**2 + x = 2*N
x**2 + x - 2*N = 0
Solving this quadratic we get
Since the number x is not negative we can't have
So we're left with
For N = 6
A perfect Integer. But for N = 12
which is 8.845 / 2 which is a fraction. The floor value is 4, which is the answer.
In short: Implement a function
f(N) = (int) ((-1.0 + sqrt(1 + 8*N))/2.0 )
i.e.
int max_partition_length(int n){
return (int)((-1.0 + sqrt(1 + n*8))/2);
}
I am stuck in a program while finding modulus of division.
Say for example I have:
((a*b*c)/(d*e)) % n
Now, I cannot simply calculate the expression and then modulo it to n as the multiplication and division are going in a loop and the value is large enough to not fit even in long long.
As clarified in comments, n can be considered prime.
I found that, for multiplication, I can easily calculate it as:
((a%n*b%n)%n*c%n)%n
but couldn't understand how to calculate the division part then.
The problem I am facing is say for a simple example:
((7*3*5)/(5*3)) % 11
The value of above expression would be 7
but if I calculate the multiplication, modulo, it would be like:
((7%11)*(3%11))%11 = 10
((10%11)*(5%11))%11 = 6
now I am left with 6/15 and I have no way to generate correct answer.
Could someone help me. Please make me understand the logic by above example.
Since 11 is prime, Z11 is a field. Since 15 % 11 is 4, 1/15 equals 3 (since 3 * 4 % 11 is 1). Therefore, 6/15 is 6 * 3 which is 7 mod 11.
In your comments below the question, you clarify that the modulus will always be a prime.
To efficiently generate a table of multiplicative inverses, you can raise 2 to successive powers to see which values it generates. Note that in a field Zp, where p is an odd prime, 2p-1 = 1. So, for Z11:
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 5
2^5 = 10
2^6 = 9
2^7 = 7
2^8 = 3
2^9 = 6
So the multiplicative inverse of 5 (which is 24) is 26 (which is 9).
So, you can generate the above table like this:
power_of_2[0] = 1;
for (int i = 1; i < n; ++i) {
power_of_2[i] = (2*power_of_2[i-1]) % n;
}
And the multiplicative inverse table can be computed like this:
mult_inverse[1] = 1;
for (int i = 1; i < n; ++i) {
mult_inverse[power_of_2[i]] = power_of_2[n-1-i];
}
In your example, since 15 = 4 mod 11, you actually end up with having to evaluate (6/4) mod 11.
In order to find an exact solution to this, rearrange it as 6 = ( (x * 4) mod 11), which makes clearer how the modulo division works.
If nothing else, if the modulus is always small, you can iterate from 0 to modulus-1 to get the solution.
Note that when the modulus is not prime, there may be multiple solutions to the reduced problem. For instance, there are two solutions to 4 = ( ( x * 2) mod 8): 2 and 6. This will happen for a reduced problem of form:
a = ( (x * b) mod c)
whenever b and c are NOT relatively prime (ie whenever they DO share a common divisor).
Similarly, when b and c are NOT relatively prime, there may be no solution to the reduced problem. For instance, 3 = ( (x * 2) mod 8) has no solution. This happens whenever the largest common divisor of b and c does not also divide a.
These latter two circumstances are consequences of the integers from 0 to n-1 not forming a group under multiplication (or equivalently, a field under + and *) when n is not prime, but rather forming simply the less useful structure of a ring.
I think the way the question is asked, it should be assumed that the numerator is divisible by the denominator. In that case the finite field solution for prime n and speculations about possible extensions and caveats for non-prime n is basically overkill. If you have all the numerator terms and denominator terms stored in arrays, you can iteratively test pairs of (numerator term, denominator term) and quickly find the greatest common divisor (gcd), and then divide the numerator term and denominator term by the gcd. (Finding the gcd is a classical problem and you can easily find a simple solution online.) In the worst case you will have to iterate over all possible pairs but at some point, if the denominator indeed divides the numerator, then you'll eventually be left with reduced numerator terms and all denominator terms will be 1. Then you're ready to apply multiplication (avoiding overflow) the way you described.
As n is prime, dividing an integer b is simply multiplying b's inverse. That is:
(a / b) mod n = (a * inv(b)) mod n
where
inv(b) = (b ^ (n - 2)) mod n
Calculating inv(b) can be done in O(log(n)) time using the Exponentiation by squaring algorithm. Here is the code:
int inv(int b, int n)
{
int r = 1, m = n - 2;
while (m)
{
if (m & 1) r = (long long)r * b % n;
b = (long long)b * b % n;
m >>= 1;
}
return r;
}
Why it works? According to Fermat's little theorem, if n is prime, b ^ (n - 1) mod n = 1 for any positive integer b. Therefore we have inv(b) * b mod n = 1.
Another solution for finding inv(b) is the Extended Euclidean algorithm, which needs a bit more code to implement.
I think you can distribute the division like
z = d*e/3
(a/z)*(b/z)*(c/z) % n
Remains only the integer division problem.
I think the problem you had was that you picked a problem that was too simple for an example. In that case the answer was 7 , but what if a*b*c was not evenly divisible by c*d ? You should probably look up how to do division with modulo first, it should be clear to you :)
Instead of dividing, think in terms of multiplicative inverses. For each number in a mod-n system, there ought to be an inverse, if certain conditions are met. For d and e, find those inverses, and then it's all just multiplying. Finding the inverses is not done by dividing! There's plenty of info out there...
I want to do the following things:
I use a variable int a to keep the input from the console, and then I do the following:
int b = a / 16;
When a is 64 or 32, I get 4 or 2. But if a is 63, I expect to get 4, but I get 3. Are there any ways in C to get a rounded value?
Edit. More details:
rang 1 to 16 should get 1,
rang 17 to 32 should get 2,
rang 33 to 48 should get 3,
rang 49 to 64 should get 4
When you use the division operator / with two int arguments, it will returns an int representing the truncated result.
You can get a rounded-up division without using floating point numbers, like this :
int a;
int den = 16;
int b = (a + den - 1) / den;
Which will give you what you expect :
a ∈ [0], b = 0 / 16 = 0,
a ∈ [1, 16], b = [16, 31] / 16 = 1,
a ∈ [17, 32], b = [32, 47] / 16 = 2,
a ∈ [33, 48], b = [48, 63] / 16 = 3,
a ∈ [49, 64], b = [64, 79] / 16 = 4,
...
Note that this only work if a and b are positives, and beware of the possible overflow of a + den.
If a + den is suspected to possibly overflow, then you could use another version of this expression :
int b = (a - 1) / den + 1;
The only downside is that it will return 1 when a = 0. If that's an issue, you can add something like :
int b = (a - 1) / den + 1 - !a;
Note that you can also handle negative values of a the same way (round away from zero) :
int b = (a > 0) ? (a - 1) / den + 1 : (a - den + 1) / den;
Integer division / in C does not do rouding, instead, it does truncation.
Solution
int ans, newNo;
int no = 63; // Given number
int dNo = 16; // Divider
newNo = (no % dNo) ? (dNo - (no % dNo) + no) : no; // Round off number
ans = newNo / dNo;
Edit
Optimize solution
ans = (no / dNo) + !!(no % dNo);
whatever you are trying is conceptualy not correct but still if you want the same result as you said in your question , you can try for standard function double ceil(double x) defined in math.h
Rounds x upward, returning the smallest integral value that is not less than x.
The simplest way to get what you want is to use float numbers.
#include <math.h>
#include <stdio.h>
int main(void)
{
double a = 63.0;
double b = 16.0;
printf("%d", (int) round(a / b));
return 0;
}
Carefully pay attention when casting from float numbers to int, and vise versa. For example, round(63/16) is incorrect. It returns a double, but achieves nothing, since the literals 63 and 16 are integers. The division is done before the value is passed to the function. The correct way is to make sure that one or both operands are of type double: round(63.0 / 16.0)
You can try using following
int b = (int)ceil((double)a/16);
Since C int division always rounds towards zero, a simple trick you can use to make it round evenly is to add "0.5" to the number before the rounding occurs. For example, if you want to divide by 32, use
x = (a+16)/32;
or more generally, for a/b, where a and b are both positive:
x = (a+b/2)/b;
Unfortunately negative numbers complicate it a bit, because if the result is negative, then you need to subtract 0.5 rather than add it. That's no problem if you already know it will be positive or negative when you're writing the code, but if you to deal with both positive and negative answers it becomes messy. You could do it like this...
x = (a+((a/b>0)?1:-1)*(b/2)) / b;
but by that stage it's starting to get pretty complex - it's probably better to just cast to float and use the round function.
--
[Edit] as zakinster pointed out, although the question asked for 'round' values, the examples given actually require ceil. The way to do that with ints would be:
x = (a+b-1)/b;
again, if the answer can be negative this gets complicated:
x = (a+((a/b>0)?1:-1)*(b-1)) / b;
I'll leave my original response for even rounding just in case someone is interested.
I'm writing code for a microprocessor with fast integer arithmetic and not so fast float arithmetic. I need to divide an integer by a number from 1 to 9 and convert result back to integer.
I made a float array with members like 0, 1, 0.5, 0.3333 etc.
But i think there is MAGIC constants (like 0x55555556) for a numbers except (1/3).
What are this numbers?
If the division instruction on your microcontroller is fast enough, use that. If you need the fractional part of the result, you may be able to use the remainder; on most architectures, the division instruction puts the quotient in one register and the remainder in another.
If your division instruction is not fast enough but the multiplication instruction is, you can use the following technique (and it sounds as if this is the technique you're after). On most architectures, multiplying a 32-bit number by another 32-bit number results in a 64-bit result; the more significant half is stored in one register and the less significant half is stored in the other. You can exploit this by realizing that division by a number n is the same as multiplying by (2^32)/n, then taking the more significant 32 bits of the result. In other words, if you want to divide by 3, you can instead multiply by 0x100000000/3 = 0x55555555, then take the more significant 32 bits of the result.
What you're doing here is really a form of fixed-point arithmetic. Take a look at the Wikipedia article for more information.
I'm assuming, based on the micro-controller tag, you don't have a fast integer divide. My answer is also for unsigned values - it will work for signed values, you just have to limit the numbers used in the tricky bit below.
A good start is divide by 2, 4 and 8. These can be done with right shifts of 1, 2 and 3 bits respectively, assuming your CPU has a logical right-shift instruction.
Secondly, dividing by 1 is just keeping the number as-is. That just leaves, 3, 5, 6, 7 and 9.
Tricky bit starts here:
For the other numbers, you can use the fact that a divide can be replaced by a multiply-and-shift.
Let's say you have a 16-bit processor. To divide by N, you multiply by 256/N and shift right 8 bits:
N = 3, multiply by 85
N = 5, multiply by 51
N = 6, multiply by 43
N = 7, multiply by 37
N = 9, multiply by 28
Take the random example of 72 / 5. Multiply 72 by 51 to get 3672 then shift right 8 bits to get 14.
In order for this to work, your numbers that you're using must not overflow the 16 bits. Since your worst case is multiply-by-85, you can handle numbers up to 771.
The reason this works is because a shift-right of 8 bits is the same as dividing by 256, and:
m * (256 / n) / 256
= m / (n / 256) / 256
= m / n * 256 / 256
= m / n * (256 / 256)
= m / n
If you have a 32-bit processor, the values and ranges change somewhat, since it's 65536/N:
N = 3, multiply by 21,846, right shift 16 bits, max value roughly 196,600.
N = 5, multiply by 13,108.
N = 6, multiply by 10,923.
N = 7, multiply by 9,363.
N = 9, multiply by 7,282.
Again, let's choose the random 20,000 / 7: 20,000 multiplied by 9,363 is 187,260,000 and, when you right shift that 16 bits, you get 2,857 - the real result is 2,857.
The following test program in C shows the accuracy figures for the values given. It uses signed values so is only good up to about 98,000 but you can see that the largest error is 1 and that it occurs at the low point of 13,110 (only 0.008% error).
#include <stdio.h>
int res[5] = {0};
int low[5] = {-1,-1,-1,-1,-1};
int da[] = {3,5,6,7,9};
int ma[] = {21846,13108,10923,9363,7282};
int main (void) {
int n, i;
for (n = 0; n < 98000; n++) {
for (i = 0; i < sizeof(da)/sizeof(da[0]); i++) {
int r1 = n / da[i];
int r2 = (n * ma[i])>>16;
int dif = abs (r1-r2);
if (dif >= 5) {
printf ("%d / %d gives %d and %d\n", n, da[i], r1, r2);
return 1;
}
res[dif]++;
if (low[dif] == -1) {
low[dif] = n;
}
}
}
for (i = 0; i < sizeof(res)/sizeof(res[0]); i++) {
printf ("Difference of %d: %6d, lowest value was %6d\n", i, res[i], low[i]);
}
return 0;
}
This outputs:
Difference of 0: 335874, lowest value was 0
Difference of 1: 154126, lowest value was 13110
Difference of 2: 0, lowest value was -1
Difference of 3: 0, lowest value was -1
Difference of 4: 0, lowest value was -1