In Project Euler's problem 9, I encounter a problem: infinite loops.
Here is my code:
#include <iostream>
#include <cmath>
bool isPythagorean(int a, int b, int c);
int main(){
int a;
int aa;
int b;
int bb;
int c;
for(a = 0; a <= 1000; a++){ /*a loop*/
aa = a;
for(b = aa; b <= 1000; b++){ /*b loop*/
bb = b;
for(c = bb; c <= 1000; c++){
if(isPythagorean(a,b,c)){
if(a + b + c == 1000){
std::cout << (a * b) * c;
return 0;
}
else
continue;
}
}
}
return 1;
}
bool isPythagorean(int a, int b, int c){
int Pa = (int) pow(a, 2);
int Pb = (int) pow(b, 2);
int Pc = (int) pow(c, 2);
if(a < b && b < c){
if(Pa + Pb == Pc)
return true;
else
return false;
}
else
return false;
}
Courtesy of everyone who has helped the idiot writing this, the code has been changed, but the error still stands:
When the code is run, nothing is output to the terminal. Could anyone kindly tell me what is going wrong here?
(I am such an idiot; My thanks go to everyone that is even looking at this.)
Thank you, istrandjev for noticing a whole host of bad pieces of code.
Thank you, Blastfurnace for noticing that stupid error.
I don't get much of the logic you are trying to apply. What is a%1==0&&b%1==0&c%1==0 checking? You can simply write it if(true), you know. Also when is the cycle supposed to end? How is a triplet supposed to be Pythagorean if one of the conditions is a > c and then you want to have a*a + b*b == c*c?
Related
I am trying to implement a Bisection Root Finding Algorithm from scratch, and the equation I am passing it is x^2 - 42 = 0. My code keeps giving the output "The root of 42 is 0 within an error of 1e-05. ", meaning that the recursion stack of my bisection algo keeps returning 0 for some reason. The code is below:
#include <iostream>
#include <cmath>
using namespace std;
class Bisection
{
public:
double a;
double b;
double c;
double epsilon;
void set_values(double, double, double);
double f(double x)
{
return x*x - 42;
}
double solve(double a, double b, double epsilon)
{
c = (a+b)/2.0;
if(abs(f(c)) < epsilon)
{
return c;
}
else
{
if (f(a) * f(c) < 0.0)
{
b = c;
solve(a, b, epsilon);
}
else if (f(c) * f(b) < 0.0)
{
a = c;
solve(a, b, epsilon);
}
}
return 0;
}
};
void Bisection::set_values(double left, double right, double error)
{
a = left;
b = right;
epsilon = error;
}
int main()
{
Bisection myObj;
myObj.set_values(0.0, 10.0, 0.00001);
//cout << myObj.f(7);
cout << "The root of 42 is " << myObj.solve(myObj.a, myObj.b, myObj.epsilon) << " within an error of " << myObj.epsilon << ".";
return 0;
}
I had to include the "return 0;" line because my compiler was throwing back "non-void function does not return a value in all control paths" without it. How can I change my code to include a return value for all recursion paths but still yield the right answer? Is there an error in my fundamental design of the algorithm, or is it a simple fix?
Other problems with the code aside, you need to actually do something with the result of solve. Usually this means returning the result from solve directly until you reach the base case and return that:
double solve(double a, double b, double epsilon)
{
c = (a+b)/2.0;
if(abs(f(c)) < epsilon)
{
return c; //this is your base case
}
else
{
if (f(a) * f(c) < 0.0)
{
b = c;
return solve(a, b, epsilon);
}
else if (f(c) * f(b) < 0.0)
{
a = c;
return solve(a, b, epsilon);
}
}
}
i tried making a program like this for schoolwork but it dosent work can somebody help me please, i dont really know where to go
#include <iostream>
using namespace std;
int main()
{
int a;
int b;
int c;
int d;
cout<<"enter 3 numbers"<<endl;
cin>>a;
cin>>b;
cin>>c;
d = a + b + c
if ( a <= 1 - = 0 )
cout<<d<<endl;
if ( b < 1 - = 0 )
cout<<d<<endl;
else ( c < 1 - = 0 )
return 0;
You may want to try something like this:
int d = 0; // Initial value
if (a > 0)
{
d = d + a;
}
if (b > 0)
{
d = d + b;
}
if (c > 0)
{
d = d + c;
}
In the above code, terms are only added to the d variable if they are positive.
So i have a function
Vector getNthRoots(double a, double b, double c, int n)
{
Vector v;
int i;
v.length = 0;
double m, a2, b2, c2;
if (n % 2 == 0)
{
a2 = a;
b2 = b;
c2 = c;
if (a<0)
a2 = a*(-1);
if (b<0)
b2 = b*(-1);
if (c<0)
c2 = c*(-1);
m = floor(pow(max(a2, b2, c2),1/n));
for (i = 1; i <= m; i++)
if (pow(i, n) >= min(a2, b2, c2) && pow(i, n) <= max(a2, b2, c2))
{
v.values[v.length] = i;
v.length++;
v.values[v.length] = (-1)*i;
v.length++;
}
return v;
}
else {
for (i = ceil(pow(min(a, b, c),1/n)); i <= floor(pow(max(a, b, c),1/n)); i++)
if (pow(i, n) >= min(a, b, c) && pow(i, n) <= max(a, b, c))
{
v.values[v.length] = i;
v.length++;
}
return v;
}
}
This function is supposed to give you the numbers at power n (number^n) which are in the interval of min(a,b,c) and max(a,b,c);
Other functions/headers
double max(double a, double b, double c)
{
if (a >= b && a >= c)
return a;
if (b >= a && b >= c)
return b;
if (c >= a && c >= b)
return c;
return a;
}
double min(double a, double b, double c)
{
if (a <= b && a <= c)
return a;
if (b <= a && b <= c)
return b;
if (c <= a && c <= b)
return c;
return a;
}
#include <iostream>
#include <cmath>
using namespace std;
#define MAX_ARRAY_LENGTH 100
struct Vector
{
unsigned int length;
int values[MAX_ARRAY_LENGTH];
};
It seems i can`t receive the good answer . For example
for getNthRoots(32,15,37,5) it should return a vector [2] because 2^5 =32 which belongs to interval [15,37] but i don`t receive anything
or getNthRoots(32,1,7,5) it should return a vector [1,2] but i only receive 1 as answer
I am guessing here is the problem for (i = ceil(pow(min(a, b, c),1/n)); i <= floor(pow(max(a, b, c),1/n)); i++)but i don`t know how i could fix it
1/n evaluates to 0, because it is evaluated as an integer expression. Try replacing all the "1/n"s with "1.0/n"s.
Take care to handle the case where n is 0.
I read the binary gcd algorithm and tried to implement it .It worked. This is my code
int gcd2(int a, int b) {
int sh;
if (a == 0)
return b;
if (b == 0)
return a;
for (sh = 0; !((a | b) & 1); sh++) {
a >>= 1;
b >>= 1;
}
while (!(a & 1)) {
a >>= 1;
}
while(b) {
while (!(b & 1)) {
b >>= 1;
}
if (a > b) {
int t = a;
a = b;
b = t;
}
b = b - a;
}
return a << sh;
}
But doesn't work if I replace the last if with
if (b > a)
{
int t = a;
a = b;
b = t;
}
b = a -b;
I just thought that both should work since they are doing the same.But it doesn't work.
Can anyone explain it please?
Thanks in advance!
it is not the same: if you choose your second way, there is the chance that a always stays bigger then b. then you never get to svap variables, and b is always less then a after b=a-b, if b is positive
i think using
a=a-b
instead of
b=a-b
could do it
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