Given following in C++:
$$k = 2^a \cdot b,$$
only knowing the value of k and that b is odd. How do you find the value for a and the value for b?
I did consider the following:
if k is odd, a has to be zero and b is k
if k is even, I would go through all possible b's with a for-loop and check if k % b == 0. If that is the case, I would take log2(k/b) and if that gives me back an integer, b = k/b and a = log2(b).
My problem: how do I check if log2(k/b) gives me back an integer?
C++ code:
Big k(9);
int r = 4;
int n = pow(2,r);
if (k % 2 == 1)
{
a = 0;
b = k;
}
else
{
for (int b = 1; b < n; b += 2)
{
if (k % b == 0 && LOGARITHM OF k / b IS POSSIBLE)
{
a = log2(b);
}
}
}
By the way: n is given as well. Everything but a and b is given.
You might do the following:
int a = 0;
while (k % 2 == 0) {
++a;
k /= 2;
}
int b = k;
// you have a, b
idest, divide by 2 the number 2**a*b until it is no longer even, so you found b.
Assuming k is unsigned int,
#include <bit>
...
int a = std::countr_zero(k);
unsigned int b = k >> a;
Related
As an answer to a particular problem, I have to print n*k^n - (n-1)*k.
for(i=0;i<n;i++){
c=(c%p*k%p)%p;
c=(c%p*n%p)%p;
d=((n-1)%p*k%p)%p;
s=(c%p-d%p)%p;
cout<<s<<endl;
}
Initially c=1, p=1000000007 and s is my final answer.
I have to take the modulo of s with respect to p.
For large values of n, s becomes negative. This happens because the modulo value changes. So even if c>d, it is possible that c%p<d%p. For n=1000000000 and k=25, s=-727999801. I am not being able to think of a suitable workaround.
-2 % 7 = 5, because -2 = 7 * (-1) + 5, while c++ modulo operation would return -2, so to get positive number you just need to add p.
if (s < 0) s += p;
I advise you to rewrite your code in the following way:
for (int i = 0; i < n; i++) {
c = (c * (k % p)) % p;
}
c = (c * (n % p)) % p;
int d = ((n - 1) % p * (k % p)) % p;
int s = (c - d) % p;
if (s < 0) s += p;
cout << s << endl;
To check with some small inputs you can use the following line:
cout << (n * (int)pow(k, n) - (n-1)*k) % p << endl;
Try to run with this input:
const int n = 5;
const int p = 7;
const int k = 10;
int c = 1;
You will see that without if (s < 0) s += p; it is -1. This line fixes it to 6 - the right answer.
I'm trying to convert these 3 loops:
for (a = 1; a < amax; a++) {
for (b = 1; b < bmax; b++) {
for (c = 1; c < cmax; c++) {
...
}
}
}
to a single loop.
I've tried this:
for (abc = 0; abc < (amax * bmax * cmax); ++abc)
{
a = abc / (bmax * cmax) + 1;
b = (abc % (bmax * cmax)) / cmax + 1;
c = (abc % (bmax * cmax)) % cmax + 1;
...
}
however it is not equivalent. Where's the logic error?
The a loop has amax-1 iterations, not amax iterations. Ditto for the b and c loops. So, the single loop should have (amax-1)*(bmax-1)*(cmax-1) iterations.
To extract the a, b and c values treat the single loop index as a mixed base number (the bases you multiplied to find the number of iterations), that is, simple integer division and remainder operations.
Add 1 to each of the resulting values.
Your first loop runs far less than second loop.
Imagine
int amax = 3;
int bmax = 3;
int cmax = 3;
Your first loop has 2, 2, 2 = 8 iterations.
Second loop will run through 0 to < (3 * 3* 3 = 27) i.e. 27 times
Also there are few more issues in the computation of a,b,c checkout the following/ Notice abc starts at 1 and the condition is <=:-
(Code in c - haven't touched c++ since ages)
int x = 1;
amax-=1;
bmax-=1;
cmax-=1;
int a = 1, b = 1, c = 1;
for (int abc = 1; abc <= (amax * bmax * cmax); ++abc)
{
c = abc % cmax;
c = c != 0 ? c : cmax;
var m = ' a='+a+' b='+b+' c='+c+' ::::'+(x++);
printf("%s\n", m);
a = abc < (bmax*cmax) || abc % ((bmax*cmax)) != 0 ? a : (a + 1) % amax;
a = a != 0 ? a : amax;
b = abc < cmax || abc % (cmax) != 0 ? b : (b + 1) % bmax;
b = b != 0 ? b : bmax;
}
How to compute combination for large number in c++? (eg. nCr n=1000 and r=500) Requirement is of last 9 digits of combination. I tried using long long int variable but still my code is able to solve and display last 9 digits of 50C19 but not more than that.
const long int a = 1000000000;
long long int ncr(int n,int r)
{
long long int fac1 = 1,fac2=1,fac;
for(int i=r;i>=1;i--,n--)
{
fac1 = fac1 * n;
if(fac1%i==0)
fac1 = fac1/i;
else
fac2 = fac2 * i;
}
fac = fac1/fac2;
return fac%a;
}
Just store the factors of the numerator in an array and divide out each factor of the denominator where possible. Finally take the product of the reduced numerators mod 10^9.
Here is some code for your specific example. You need to write a gcd() function.
int a[] = { 1000,999,...,501 }; // numerator factors
for (int b = 2; b <= 500; b++) {
int x = b;
for (int i = 0; i < 500; i++) {
int d = gcd(x, a[i]);
if (d > 1) {
x = x / d;
a[i] = a[i] / d;
if (x <= 1) break;
}
}
}
// take the product of a[] mod 10^9
int ans = 1;
for (int i = 0; i < 500; i++) {
ans = (ans * a[i]) % 1000000000;
}
// ans = C(1000,500) mod 10^9
A good discussion of other techniques is available here:
http://discuss.codechef.com/questions/3869/best-known-algos-for-calculating-ncr-m
I'm working on problem 9 in Project Euler:
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
The following code I wrote uses Euclid's formula for generating primes. For some reason my code returns "0" as an answer; even though the variable values are correct for the first few loops. Since the problem is pretty easy, some parts of the code aren't perfectly optimized; I don't think that should matter. The code is as follows:
#include <iostream>
using namespace std;
int main()
{
int placeholder; //for cin at the end so console stays open
int a, b, c, m, n, k;
a = 0; b = 0; c = 0;
m = 0; n = 0; k = 0; //to prevent initialization warnings
int sum = 0;
int product = 0;
/*We will use Euclid's (or Euler's?) formula for generating primitive
*Pythagorean triples (a^2 + b^2 = c^2): For any "m" and "n",
*a = m^2 - n^2 ; b = 2mn ; c = m^2 + n^2 . We will then cycle through
*values of a scalar/constant "k", to make sure we didn't miss anything.
*/
//these following loops will increment m, n, and k,
//and see if a+b+c is 1000. If so, all loops will break.
for (int iii = 1; m < 1000; iii++)
{
m = iii;
for (int ii = 1; n < 1000; ii++)
{
n = ii;
for (int i = 1; k <=1000; i++)
{
sum = 0;
k = i;
a = (m*m - n*n)*k;
b = (2*m*n)*k;
c = (m*m + n*n)*k;
if (sum == 1000) break;
}
if (sum == 1000) break;
}
if (sum == 1000) break;
}
product = a * b * c;
cout << "The product abc of the Pythagorean triplet for which a+b+c = 1000 is:\n";
cout << product << endl;
cin >> placeholder;
return 0;
}
And also, is there a better way to break out of multiple loops without using "break", or is "break" optimal?
Here's the updated code, with only the changes:
for (m = 2; m < 1000; m++)
{
for (int n = 2; n < 1000; n++)
{
for (k = 2; (k < 1000) && (m > n); k++)
{
sum = 0;
a = (m*m - n*n)*k;
b = (2*m*n)*k;
c = (m*m + n*n)*k;
sum = a + b + c;
if ((sum == 1000) && (!(k==0))) break;
}
It still doesn't work though (now gives "1621787660" as an answer). I know, a lot of parentheses.
The new problem is that the solution occurs for k = 1, so starting your k at 2 misses the answer outright.
Instead of looping through different k values, you can just check for when the current sum divides 1000 evenly. Here's what I mean (using the discussed goto statement):
for (n = 2; n < 1000; n++)
{
for (m = n + 1; m < 1000; m++)
{
sum = 0;
a = (m*m - n*n);
b = (2*m*n);
c = (m*m + n*n);
sum = a + b + c;
if(1000 % sum == 0)
{
int k = 1000 / sum;
a *= k;
b *= k;
c *= k;
goto done;
}
}
}
done:
product = a * b * c;
I also switched around the two for loops so that you can just initialize m as being larger than n instead of checking every iteration.
Note that with this new method, the solution doesn't occur for k = 1 (just a difference in how the loops are run, this isn't a problem)
Presumably sum is supposed to be a + b + c. However, nowhere in your code do you actually do this, which is presumably your problem.
To answer the final question: Yes, you can use a goto. Breaking out of multiple nested loops is one of the rare occasions when it isn't considered harmful.
I'm well aware this brute force method is bad and that I should be using something like Euclid's formula, and that the final loop isn't needed as c = 1000 - (a + b) etc... but right now I just want this to work.
bool isPythagorean(int a, int b, int c) {
if((a*a + b*b) == c*c && a < b && b < c) {
cout << a << " " << b << " " << c << endl;
return true;
} else {
return false;
}
}
int main()
{
int a = 1;
int b = 2;
int c = 3;
for(a = 1; a < b; ++a) {
for(b = 2; b < c; ++b) {
for(c = 3; a + b + c != 1000 && !isPythagorean(a, b, c); ++c) {
}
}
}
return 0;
}
For the most part, the code works as I expect it to. I cannot figure out why it is stopping shy of a + b + c = 1000.
My final triplet is 280 < 294 < 406, totalling 980.
If I remove the a < b < c check, the triplet becomes 332, 249, 415 totalling 996.
All results fit the pythagorean theorem -- I just cannot land a + b + c = 1000.
What is preventing me?
This part of the code iterates very strangely:
for(a = 1; a < b; ++a) {
for(b = 2; b < c; ++b) {
for(c = 3; a + b + c != 1000 && !isPythagorean(a, b, c); ++c) {
}
}
}
Initially, a = 1, b = 2, c = 3. But upon the first for(c), c=997, so the second iteration of for(b) will run up to b=996. Keep doing this, and at some point you find a triple (a,b,c), at that point, c is probably not close to 1000, b will iterate up to whatever state c was is in... and so on. I don't think you can accurately predict the way it's going to come up with triples.
I suggest you go with something like
for(a = 1; 3*a < 1000; ++a) {
for(b = a+1; a+2*b < 1000; ++b) {
for(c = b+1; a + b + c != 1000 && !isPythagorean(a, b, c); ++c) {
}
}
}
That way, loops won't depend on the previously found triple.
... and you really should use Euclid's method.
The condition in your innermost for loop explicitly says to never test anything where a + b + c is equal to 1000. Did you mean a + b + c <= 1000?
Alternate possible Solution:
#include <iostream>
#define S(x) x*x
int main() {
int c = 0;
for(int a=1;a<(1000/3);++a) {
// a < b; so b is at-least a+1
// If a < b < c and a + b + c = 1000 then 'a' can't be greater than 1000/3
// 'b' can't be greater than 1000/2.
for(int b=a+1;b<(1000/2);++b) {
c = (1000 - a - b); // problem condition
if(S(c) == (S(a) + S(b) ))
std::cout<<a*b*c;
}
}
return 0;
}
For additional reference please refer the following posts
Finding Pythagorean Triples: Euclid's Formula
Generating unique, ordered Pythagorean triplets