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;
}
Related
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;
My code goes like this:
if (x[b] != x[c] && x[a] != x[b])
{
if(x[a] != x[b] != x[c] != x[d])
{
if(y[a] != y[b] != y[c] != y[d])
{
int m = (y[a] - y[b])/(x[a] - x[b]);
int b = y[a] - x[a] * m;
if((y[c] - x[c]*m > b && y[d] - x[d]*m > b)|| (y[c] - x[c]*m < b && y[d] - x[d]*m < b)){
m = (y[b] - y[c])/(x[b] - x[c]);
b = y[b] - x[b] * m;
if((y[a] - x[a]*m > b && y[d] - x[d]*m > b)|| (y[a] - x[a]*m < b && y[d] - x[d]*m < b))
{
int xx[4];
int yy[4];
xx[0] = x[a];
xx[1] = x[b];
xx[2] = x[c];
xx[3] = x[d];
yy[0] = y[a];
yy[1] = y[b];
yy[2] = y[c];
yy[3] = y[d];
if(c == 1)
{
c = 0;
pt = povrsina(xx, yy);
pc = p - pt;
}
pv = povrsina(xx, yy);
pr = p - pv;
if(pr < pc)
{
pc = pr;
pt = pv;
}
else if(pr == pc)
{
pt = max(pt, pv);
}
}
}
}
}
}
The input I have tried is this:
5
30
0 0
10 0
0 10
10 10
7 3
My program crashes with an error code for Division by zero in line 174:
m = (y[b] - y[c])/(x[b] - x[c]);
So I added the first if statement checking
if x[b] != x[c]
but it still crashes for some reason with the same error code and in the same line.
The following works correctly.
int n = 0;
double p = 0;
scanf("%d\n%lf", &n, &p);
int *x = (int *) malloc(sizeof(int) * n);
int *y = (int *) malloc(sizeof(int) * n);
for(int i = 0; i < n; i++){
scanf("%d %d", &x[i], &y[i]);
}
for(int i = 0; i < n; i++){
printf("%d %d\n", x[i], y[i]);
}
See the demo.
Update
Your code is crashing because of the following line.
int m = (y[a] - y[b])/(x[a] - x[b]);
Think if the value of a, b, c, d is 0, 2, 3, 4, then the denominator term (x[a] - x[b]) represents (x[0] - x[2]) which is equal to zero, right? Because the 1st and 3rd input is 0 0 and 0 10.
If you divide a value by zero, then it becomes infinity and your program will crash at that time. While writing statement with division operation, make sure the divisor is not zero.
I made this function that calculates the prime factorization of a number (n) which is obtained from the user. I am having issues with it due to the fact that It does not print the same factor more than once.
For Example:
The Prime Factorization of 3960 is:
11 5 3 3 2 2 2
However my program only prints out:
11 5 3 2
Can anyone help me to identify the cause and help me find a solution?
void primefact(int n)
{
Stack f;
assert(n >= 0);
bool prime;
for(int d = 2; d <= n; d++) // Test for factors > 1
{
if(n % d == 0)
{
prime = true;
for(int j = 2; j < d; j++) // Test for prime
{
if(d % j == 0) // It is not prime
prime = false;
}
if(prime)
f.push(d);
}
}
while(!f.empty())
{
cout << f.top() << endl;
f.pop();
}
}
You have to loop over the same prime as long as it divides the input.
Can anyone help me to identify the cause?
You're checking whether n is divisible by d, but then you move on to the next value. If n is divisible by d and d is prime, you need to actually divide n by d and check d again.
Let's take 12 as an example. Prime factors are [3, 2, 2]. Your code does this:
n = 12, d = 2
n % d == 0? Yes. Push d. d = d + 1
n % d == 0? Yes. Push d. d = d + 1
n % d == 0? No. d = d + 1
n % d == 0? No. d = d + 1
n % d == 0? No. d = d + 1
n % d == 0? No. d = d + 1
// and so on until d == n
You want code that does this:
n = 12, d = 2
n % d == 0? Yes. Push d. n = n/d // n is 6, d is 2
n % d == 0? Yes. Push d. n = n/d // n is 3, d is 2
n % d == 0? No. d = d + 1 // n is 3, d is 3
n % d == 0? Yes. Push d. n = n/d // n is 1 so you're done
You probably know yourself that your algorithm is far from optimal. So this won't hurt the performance much. Replace
if(prime)
f.push(d);
with
if (prime)
{
for (int d1 = d; n % d1 == 0; d1 *= d)
f.push(d);
}
Simplest code for prime factorization:-
for ( int i = 2; i <= num; ++i )
{
while ( num % i == 0 )
{
num /= i;
std::cout << i << std::endl;
}
}
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