I am writing a code for GCD in C++ but I am encountering a mysterious error that I can't seem to think of its probable reason.
In the below program if both the numbers are equal to i ... it will break and return the value of i.
But it doesn't seems to work because it outputs the result as 1.
int gcd2(int a, int b) {
int i,hcf=0;
if (b > a) {
a = a + b;
b = a - b;
a = a - b;
}
for (i = 1; i <= b; ++i) {
if (a % i == 0 && b % i == 0) {
break;
}
}
return i;
}
But when I add a variable HCF in the same code :
int gcd2(int a, int b) {
int i,hcf=0;
if (b > a) {
a = a + b;
b = a - b;
a = a - b;
}
for (i = 1; i <= b; ++i) {
if (a % i == 0 && b % i == 0) {
hcf = i;
}
}
return hcf;
}
It works. Why is that? Can anyone clarify?
The variable hfc is not the cause for the difference you notice. If we keep the difference but introduce a hfc in both versions we have:
int hfc = 0;
for (i = 1; i <= b; ++i) {
if (some_condition(i)) {
hfc = i;
break; // breaks out of the loop
}
}
return hfc;
vs
int hfc = 0;
for (i = 1; i <= b; ++i) {
if (some_condition(i)) {
hfc = i; // no break !!!
}
}
return hfc;
The first returns the first value of i for which some_condition(i) is true. The second version returns the last value of i for which some_condition(i) is true. This and the fact that any number is divisible by 1 explains the different results you get.
The simple difference between your two samples is whether the loop goes through the whole interval and whether the first or last match is returned.
Using break makes it to stop when the first number fulfilling the condition is found. As commenters note, 1 is the divider of all numbers, so you should rather have started with i = 2. However, this variant still won’t find the greatest common divisor in all cases.
On the other hand, the variable assignment can be called multiple times, so your second sample returns the last, i.e. greatest number found which is most likely your desired result.
Related
I need to make a simple function in c++ that will say if an entered integer has its digits ascending from left to right. Ex, 123 is ascending. We just started learning recurssion, which is what I'm supposed to use, but I'm confused. So far what I was thinking is that you store the last digit as a temp, then compare that to the next digit, but how would you manage to do that?
bool ascending(int n) {
int temp = n % 10;
while (n / 10 > 0) {
n = n / 10;
if (temp > n % 10) {
return false;
break;
}
temp = n % 10;
}
}
This is the code I have so far, but I'm definitely messing up. I'm not even using recurrsion.
Here is one way you can go about it.
On every iteration, you check that last 2 digits are in order. And when the number is a single digit, return true
bool ascending(int n) {
int last_digit = n % 10;
int remainder = n / 10;
if (remainder == 0)
{
return true;
}
int second_last_digit = remainder % 10;
if (last_digit < second_last_digit)
{
return false;
}
else
{
return ascending(remainder); // Recusrive call
}
}
I know how to write a code finding a GCD of 2 number . However, I am trying to solve a problem of finding a GCD of n number and I think the algorithm is a little bit different than using an Eucledian algorithm. My code can be compiled , but it always gave me the wrong result. For example when i put n = 2 , GCD of 16 and 12 it gave the answer 8. Here is my code :
#include<iostream>
using namespace std;
int main()
{
int a,b[100],c,d,e=0;
cin>>a;
for(c=0 ; c<a ; c++)
{
cin>>b[c];
}
for(c=0 ; c<a-1 ; c++)
{
if(c < 1)
{
d = b[c];
}
if(b[c] < d)
{
d = b[c];
}
}
while(d>0)
{
for(c=0 ; c<a ; c++)
{
if(b[c] % d < 1)
{
e++;
}
}
if(e == c)
{
cout<<d;
break;
}
d--;
}
}
Can you guys please find the mistake in my code?
Your code does not compute the greatest common divisor of the input array - it counts how many of the entries are evenly divisible by the smallest element d of the array, then how many are divisible by one smaller, and so on until d is 0. This has nothing to do with the GCD at all.
One easy way - though not necessarily the fastest - would be based on the fact that the GCD of three numbers must be the same as the GCD of any one of those numbers and the GCD of the other two.
gcd(a, b, c) = gcd(gcd(a, b), c) = gcd(a, gcd(b, c)) = gcd(gcd(a, c), b)
Extension to n inputs is elementary:
int result = a[0];
for (int i = 1; i < a.Length; ++i)
result = gcd(result, a[i]);
Code for the GCD of two numbers can be found all over the 'net, for example at Rosetta Code. One of my favourites is this plain iterative version:
int gcd (int a, int b)
{
while (b)
{
int t = b;
b = a % b;
a = t;
}
return a;
}
C# allows a more succinct formulation but in other languages this probably won't work (in C++ it would invoke undefined behaviour, for example):
static int gcd (int a, int b)
{
while (b != 0)
b = a % (a = b);
return a;
}
In case some find it helpful, here is an implementation of the Euclidean algorithm in JavaScript.
function EuclideanGCD(a, b) {
// Make sure a > b, interchange values
if (a < b) {
c = a;
a = b;
b = c
}
// If A = 0 then GCD(A,B) = B and we can stop.
if (a == 0) {
return b;
// If B = 0 then GCD(A,B) = A and we can stop.
} else if (b == 0) {
return a;
} else {
let gdc = 0;
let quotient = Math.floor(a / b); // Get the divisor
let remainder = a % b; // Get the remainder
// Make a recursive call, till we hit 0
gdc = EuclideanGCD(b, remainder);
return gdc;
}
}
var gcd = EuclideanGCD(234, 357);
console.log(gcd); // Outputs: 3
I was just writing an improved linear version of a recursive Fibonacci algorithm, and realized that my boolean expressions look really bad and unreadable. Is there a cleaner way to do what I'm trying to do?
int fibonacci(int num) {
if (num <= 1)
return num;
// starts looking ugly here
int a = intExists(num-1);
int b = intExists(num-2);
bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);
int number = 0;
if (aAndB)
number = (a + b);
else if (justA)
number = (a + fibonacci(num - 2));
else if (justB)
number = (fibonacci(num-1) + b);
else
number = (fibonacci(num - 1) + fibonacci(num - 2));
map.push_back(Pair(num, number));
return number;
}
Thanks
If you're talking about:
bool aAndB = (a != -1 && b != -1);
then I would say, "no."
This code looks perfectly expressive to me. aAndB is initialized at the moment it comes in to being, and the conditions are very clear. This might look a bit odd when you're first starting out in C++, but before you know it it will be second nature and other constructs will seem silly.
One thing I would suggest is to make aAndB const if you don't intend to change it:
const bool aAndB = (a != -1 && b != -1);
This is even more expressive.
It also might give the compiler an additional opportunity to optimize your code.
Remember -- write code for humans to understand. Not for computers to understand.
Why don't you make a and b as bools and assign those as true if a == -1 and false otherwise. Then, the expressions will become easier to handle.
Could do a switch statement to clean up the if else statements a little. Other than that just add comments
You could rewrite it to use conditional branching, like this:
int fibonacci(int num) {
if (num <= 1)
return num;
int a = intExists(num-1);
int b = intExists(num-2);
const bool isA = (a != -1); // change in the definition
const bool isB = (b != -1); // change in the definition
int number = 0;
if (isA && isB)
number = (a + b);
else if (isA) // conditionnal branching
number = (a + fibonacci(num - 2));
else if (isB) // conditionnal branching
number = (fibonacci(num-1) + b);
else
number = (fibonacci(num - 1) + fibonacci(num - 2));
map.push_back(Pair(num, number));
return number;
}
I'm assuming that intExists(n) looks up map and if finds n in there, returns fibonacci(n) else it returns -1. Then you could do this:
int fibonacci(int num) {
if (num <= 1)
return num;
int a = intExists(num-1);
int b = intExists(num-2);
if (a == -1) // if a wasn't found, then compute it
a = fibonacci(num-1);
if (b == -1) // if b wasn't found, then compute it
b = fibonacci(num-2);
int number = a + b;
map.push_back(std::make_pair(num, number));
return number;
}
Bonus:
Here is another completely different implementation of fibonnacci() based on Binet's formula:
#include <cmath>
int fibonacci(int n) {
static const double e1 = 1.6180339887498948482045868343656; // = (1 + sqrt(5)) / 2
static const double e2 = -0.61803398874989484820458683436564; // = (1 - sqrt(5)) / 2
static const double c = 0.44721359549995793928183473374626; // = 1 / sqrt(5);
double f = c * (std::pow(e1, n) - std::pow(e2, n));
return static_cast<int>(f + 0.5);
}
int main() {
for (int n = 1; n < 15; ++n)
std::cout << fibonacci(n) << ' ';
}
It outputs:
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Plain C++ code is clean enough:
bool a = intExists(num-1);
bool b = intExists(num-2);
if (a && b) {
//
} else if (a) {
//
} else if (b) {
//
} else {
//
}
int a = intExists(num-1);
int b = intExists(num-2);
bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);
Quick look into the approach you took. Under what circumstances can justB be true? (Hint: never)
That should help you simplify your approach, although there are better approaches than memoization.
Changing intExists to return boolean values, you can do a switch-case statements like that:
bool a = intExists(num-1);
bool b = intExists(num-2);
switch ((a << 1) + b) {
default: // none exists
case 1: // only b exist
case 2: // only a exist
case 3: // both exists
}
The rationale is to transform those booleans in a binary number
A slightly drastic rewrite is to let an external function handle the lookup table.
That way you don't need to care about more than one value at a time.
This one uses map so I didn't have to write so much in order to test it, but it should be easy enough to adapt:
std::map<int, int> table;
int fibonacci(int num);
int value(int num)
{
int result = table[num];
if (!result)
{
result = fibonacci(num);
table[num] = result;
}
return result;
}
int fibonacci(int num)
{
if (num <= 2)
return 1;
return value(num - 1) + value(num - 2);
}
I am working on solving a mathematical problem.
What I am trying to do is to have an if statement that compares variable n to a set of variables i 1 through 10. Is there any way to do it in c++?
here is what I am trying to do:
int smallPos(int n){
if (n%for(int i=1;i<=10;i++)==0) {
return n;
}
This is obviously wrong but is any way to get around it?
It looks like you're trying to do this:
int smallPos(int n)
{
return (n % 232792560 == 0) ? n : <sentinel value>; // sentinel_value is the value return if n does not meet requirements
//232792560 is the first number for which n % a: a ∈ {1,2,3...10} This is faster than checking each of these values.
}
What you want to do is this:
int smallPos(int n)
{
for (int i = 1; i <= 10; ++i)
{
if (n % i != 0) // check if n % i == 0, if not, then we shouldn't return n.
{
return -1; // or whatever you want to return when not ALL the remainders are 0.
}
}
return n; // If we get here then all the remainders were 0s.
}
Euler published the remarkable quadratic formula:
n² + n + 41
It turns out that the formula will produce 40 primes for the consecutive
values n = 0 to 39. However, when n =
40, 40^(2) + 40 + 41 = 40(40 + 1) + 41
is divisible by 41, and certainly when
n = 41, 41² + 41 + 41 is clearly
divisible by 41.
Using computers, the incredible formula n² − 79n + 1601 was
discovered, which produces 80 primes
for the consecutive values n = 0 to
79. The product of the coefficients, −79 and 1601, is −126479.
Considering quadratics of the form:
n² + an + b, where |a| < 1000 and |b| < 1000
where |n| is the modulus/absolute value of n
e.g. |11| = 11 and |−4| = 4
Find the product of the coefficients, a and b, for the
quadratic expression that produces the
maximum number of primes for
consecutive values of n, starting with
n = 0.
This is the problem for Euler 27.
I have attempted a solution for trying to find the equation n^2 + n + 41 to see if my logic is correct then I will attempt to see if it works on the actual problem. Here is my code (I will place comments explaining the whole program also, I would start reading from the int main function first) just make sure to read the comments so you can understand my logic:
#include <iostream>
using namespace std;
bool isPrime(int c) {
int test;
//Eliminate with some simple primes to start off with to increase speed...
if (c == 2) {
return true;
}
if (c == 3) {
return true;
}
if (c == 5) {
return true;
}
//Actual elimination starts here.
if (c <= 1 || c % 2 == 0 || c % 3 == 0 || c % 5 == 0) {
return false;
}
//Then using brute force test if c is divisible by anything lower than it except 1
//only if it gets past the first round of elimination, and if it doesn't
//pass this round return false.
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
//If the c pasts all these tests it should be prime, therefore return true.
return true;
}
int main (int argc, char * const argv[]) {
//a as in n^2 + "a"n + b
int a = 0;
//b as in n^2 + an + "b"
int b = 0;
//n as in "n"^2 + a"n" + b
int n = 0;
//this will hold the result of n^2 + an + b so if n = 1 a = 1
//and b = 1 then c = 1^2 + 1(1) + 1 = 3
int c = 0;
//bestChain: This is to keep track for the longest chain of primes
//in a row found.
int bestChain = 0;
//chain: the current amount of primes in a row.
int chain = 0;
//bestAB: Will hold the value for the two numbers a and b that
// give the most consecutive primes.
int bestAB[2] = { 0 };
//Check every value of a in this loop
for (a = 0; a < 40; a++) {
//Check every value of b in this loop.
for (b = 0; b < 42; b++) {
//Give c a starting value
c = n*n + a*n + b;
//(1)Check if it is prime. And keep checking until it is not
//and keep incrementing n and the chain. (2)If it not prime then che
//ck if chain is the highest chain and assign the bestChain
// to the current chain. (3)Either way reset the values
// of n and chain.
//(1)
while (isPrime(c) == true) {
n++;
c = n*n + a*n + b;
chain++;
}
//(2)
if (bestChain < chain) {
bestChain = chain;
bestAB[0] = a;
bestAB[1] = b;
chain = 0;
n = 0;
}
//(3)
else {
n = 0;
chain = 0;
}
}
}
//Lastly print out the best values of a and b.
cout << bestAB[0] << " " << bestAB[1];
return 0;
}
But, I get the results 0 and 2 for a and b respectively, why is this so? Where am I going wrong? If it is still unclear just ask for more clarification on a specific area.
Your isprime method is inefficient -- but also wrong:
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
in the first iteration of the for loop, test = c, so c % test is just c % c, which will always be 0. So your isprime method claims everything is non-prime (other than 2, 3, 5)
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
Do you see the problem with that? If not, try working out some small sample values by hand.
As pointed out by others, your problem is in the isPrime method (test = c, so test % c = c % c == 0 is always true).
You can make your isPrime function run in O(sqrt(n)) instead of O(n) by initializing test to sqrt(c) (and only checking odd numbers). It is easy to see that if a number A is divisible by B < sqrt(A), then C = A/B must be > sqrt(A). Thus if there are no divisors < sqrt(A), there will be no divisors > sqrt(A).
Of course, you can run it a whole lot faster even, by using a probabilistic primality test, e.g. Miller-Rabin's primality test.
Also, I'm not sure, but I suspect you might reach the limit of int fairly quickly. It's probably a better idea to use unsigned long long from the start, before you start getting strange errors due to overflow & wrapping.