Not sure where this infinite loop is coming from - c++

I'm coming from C into C++, I might be missing something very basic.
I'm trying to make a program with the collatz conjecture.
Before the first iteration of the loop, i and j both correctly equal 1 and 10.
However, the value of i never seems to change although I have i++ in my loop.
I thought this would be a quick program to code but I'm getting hung up on this. Any help would be appreciated.
int n, j, i, count = 0;
cin >> n >> j;
for (i = n; i < j; i++){
while (i != 1){
if (i % 2 == 0)
i = i/2;
else
i = 3*i + 1;
}
count++;
cout << i << endl;
}

The problem in your code is that after you've run the while loop that tests whether the conjecture is true for i, i is by definition set back to 1 (since that's the condition to get out of the loop), so i++ keeps incrementing from 1 to 2 each time. You'll never get past 2.
If you're trying to test the Collatz Conjecture for all the numbers from n to j, you need to use a different variable in the while loop than you use for iteration.
And if count is supposed to tell you how many cycles are needed, you need to zero it before each while loop, and increment it inside the while loop.
int n, j, i;
cin >> n >> j;
for (i = n; i < j; i++){
int test = i;
int count = 0;
while (test != 1){
if (test % 2 == 0) {
test = test/2;
} else {
test = 3*test + 1;
}
count++;
}
cout << i << ' ' << count << endl;
}

Not sure what it's all about, but here's some quick observation:
your while(i != 1) loop means that it will either run indefinetely, or when this loop ends i will be equal to 1. Which means that your for (i = n; i < j; i++){ loops will always restart with i=1. No wonder it's a dead loop.

Before the first iteration of the loop, i and j both correctly equal 1 and 10.
The let's replay the second iteration of the outer loop.
Before it, at the end of the first iteration, i has been incremented to equal 2. Now,
i % 2 == 0 => i := i / 2, i.e. i := 1.
Now i == 1, inner loop ends.
i is incremented and now equals 2.
Repeat.

You can simply copy the loop variable to a new variable in every loop iteration i = k in this case, so that the for loop variable is not affected
#include <iostream>
int main(){
int min, max, count = 0;
std::cin >> min >> max;
for (int k = min; k <= max; ++k){
i = k;
while (i != 1)
{
if (i % 2 == 0)
i /= 2;
else
i = 3*i + 1;
count++;
std::cout << i << std::endl; //ONLY IF U WANT TO PRINT i EVERY ITERATION
}
std::cout << "Number of iterations needed: " << count << " for i = " << i << std:: endl;
}

Related

I want to know the error in my code. This is to print sum of all even numbers till 1 to N

#include<iostream>
using namespace std;
int main(){
int i = 1;
int sum;
int N;
cout << "Enter a number N: ";
cin >> N;
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
else
{
i = i + 1;
}
}
cout << sum;
}
This is to print the sum of all even numbers till 1 to N.
As I try to run the code, I am being asked the value of N but nothing is being printed ahead.
For starters the variable sum is not initialized.
Secondly you need to increase the variable i also when it is an even number. So the loop should look at least like
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
i = i + 1;
}
In general it is always better to declare variables in minimum scopes where they are used.
So instead of the while loop it is better to use a for loop as for example
for ( int i = 1; i++ < N; ++i )
{
if ( i % 2 == 0 ) sum += i;
}
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
else
{
i = i + 1;
}
}
Let's step through this. Imagine we're on the loop where i = 2 and you've entered N = 5. In that case...
while(i <= N)
2 <= 5 is true, so we loop
if(i%2 == 0)
2 % 2 == 0 is true, so we enter this branch
sum = sum + i;
Update sum, then head back to the top of the loop
while(i <= N)
Neither i nor N have changed, so 2 <= 5 is still true. We still loop
if(i%2 == 0)
2 % 2 == 0 is still true, so we enter this branch again...
Do you see what's happening here? Since neither i nor N are updated, you'll continue entering the same branch and looping indefinitely. Can you think of a way to prevent this? What would need to change?
Also note that int sum; means that sum will have a garbage value (it's uninitialized). If you want it to start at 0, you'll need to change that to
int sum = 0;
You're looping infinitly when i is even because you don't increase it.
Better option would be this if you want to use that while loop :
while(i<=N)
{
if(i%2 == 0)
sum = sum + i;
i=i+1;
}
cout << sum;
If you don't need to do anything when the condition is false, just don't use an else.
No loops are necessary and sum can be evaluated at compile time if needed too
// use unsigned, the whole excercise is pointless for negative numbers
// use const parameter, is not intended to be changed
// constexpr is not needed, but allows for compile time evaluation (constexpr all the things)
// return type can be automatically deduced
constexpr auto sum_of_even_numbers_smaller_then(const unsigned int n)
{
unsigned int m = (n / 2);
return m * (m + 1);
}
int main()
{
// compile time checking of the function
static_assert(sum_of_even_numbers_smaller_then(0) == 0);
static_assert(sum_of_even_numbers_smaller_then(1) == 0);
static_assert(sum_of_even_numbers_smaller_then(2) == 2);
static_assert(sum_of_even_numbers_smaller_then(3) == 2);
static_assert(sum_of_even_numbers_smaller_then(7) == 12);
static_assert(sum_of_even_numbers_smaller_then(8) == 20);
return 0;
}
int main(){
int input; //stores the user entered number
int sum=0; //stroes the sum of all even numbers
repeat:
cout<<"Please enter any integer bigger than one: ";
cin>>input;
if(input<1) //this check the number to be bigger than one means must be positive integer.
goto repeat; // if the user enter the number less than one it is repeating the entry.
for(int i=input; i>0; i--){ // find all even number from your number till one and than totals it.
if(i%2==0){
sum=sum+i;
int j=0;
j=j+1;
cout<<"Number is: "<<i<<endl;
}
}
cout<<endl<<"The sum of all even numbers is: "<<sum<<endl;}
Copy this C++ code and run it, it will solve your problem.
There are 2 problems with your program.
Mistake 1
The variable sum has not been initialized. This means that it has(holds) an indeterminate value. And using this uninitialized variable like you did when you wrote sum = sum + i; is undefined behavior.
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has undefined behavior.
This is why it is advised that:
always initialize built in types in local/block scope.
Mistake 2
The second problem is that you're not updating the value of variable i.
Solution
You can solve these problems as shown below:
int main(){
int i = 1;
int sum = 0; //INITIALIZE variable sum to 0
int N;
cout << "Enter a number N: ";
cin >> N;
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
i = i + 1; //update(increase i)
}
cout << sum;
}
1For more reading(technical definition of) on undefined behavior you can refer to undefined behavior's documentation which mentions that: there are no restrictions on the behavior of the program.

Possible infinite loop

I think my code has an infinite loop. Can someone tell me where I went wrong?
The code is supposed to find the number of valid numbers, with a valid number being a number without a digit repeating. For example, 1212 would be a non-valid number because 1 and 2 repeated.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int a; int b; int count_validNums = 1; int digit; int last_digit; bool is_valid = true;
vector <int> num_list;
cout << "Enter numbers 0 < a <= b < = 10000: ";
cin >> a >> b;
// Checks for invalid input
if (a < 0 || b < 0 || a > 10000 || b > 10000) {
cout << "Invalid input";
return 1;
}
// Checks every number from the range [a,b]
for (int i = a; i <= b; i++){
last_digit = i % 10;
num_list.push_back(last_digit);
i = i / 10;
while (i != 0){
digit = i % 10;
if (find(num_list.begin(), num_list.end(), digit) != num_list.end()){
is_valid = false;
}
num_list.push_back(digit);
i = i / 10;
}
if (is_valid) count_validNums++;
}
cout << "They are " << count_validNums << " valid numbers between" << a << " and " << b << endl;
}
The inner while loop terminates when i == 0. Then the outer for loop increments it (so i == 1), then the inner loop reduces it to zero again. Then the other loop increments it, then ...
What is happening to cause the infinite loop is that you are constantly reducing the int i back down to 0. Consider these highlights:
`for(int i = a; i <= b; i++){
//stuff
while(i != 0){ //<--this forces i down to 0
//more stuff
i = i / 10;
}
//final stuff
}`
i here is all one variable, so any changes you make to it anywhere will affect it everywhere else it exists! Instead, you can try saying something like int temp = i; and then perform your operations on temp so that i remains independent, but because your for-loop terminates when i <= b and you are constantly resetting i to 0, it will never reach b.
Also, I noticed that in your check for valid numbers you verify that 0 < a,b < 10000, but later in your for-loop you seem to make the assumption that a <= b will be true. Unfortunately, your test does not ensure this, so the for-loop will immediately terminate for inputs where b < a is true (which your program currently allows) and your program will report answers that are likely incorrect. The same is true when I enter letters as input instead of numbers. You might want to revisit that portion of code.

i want to show the sequence ftom 16 to 31 decimal number but its not showing :\ could anyone help me out here

#include <iostream>
using namespace std;
void bi(int a);
int main()
{
// here is the issue how do start a loop, where i want the answer from 16 to 31 numbers
int a=0;
cout<<"Baum-Sweet Sequence From 16 to 31 \n";
for(int j=a;j>16 && j<31;j++)
{
cout<<j;
}
bi(a);
system("Pause");
}
// Rest is working properly
void bi(int a)
{
int myArr[15],i=0,f=0,n=0;
for (int h = 0 ; h <= a; h++)
{
int num = h;
for (i = 0 ; i < 4 ; i++)
{
myArr[i] = num%2;
num = num/2;
}
for (int t = 0 ; t < 4 ; t++)
{
if (myArr[t]%2==0)
f++;
}
if (f%2==0)
cout << " = " << 1;
else
cout << " = " << 0;
cout <<endl;
}
}
i want to show the sequence from 16 to 31 decimal number but its not showing :\ could anyone help me out here
There is an error in the for loop.
The for loop has three parts separated by a semicolon.
for (INITIALIZATION; CONDITION; AFTERTHOUGHT)
{
// Source code for the for-loop's body
}
The first part initializes the variable (e.g. "int j = 16;" means that through the variable j you begin counting by 16);
The second part checks a condition and it quits the loop when false (e.g. j <=31 means that it quits the loop when j will have value 31);
The third one is performed once each time the loop ends and then repeats (e.g. j++ means that at each iteration of the loop j will be incremented by 1).
Each iteration will execute the code in the body of the for loop.
Considering that you want to call the bi function for each value from 16 to 31 your for loop body should include bi(j). Your main should be modified like the code below:
int main()
{
cout<<"Baum-Sweet Sequence From 16 to 31 \n";
for(int j=16;j<=31;j++)
{
cout<<j;
bi(j);
}
system("Pause");
return 0;
}
Your problem is that you set j to 0, but then make a condition for the loop that it will only execute if j (which is set to a), is bigger than 16.
Your first thing to do is to make the loop conditions this:
for (int j = 16; j <= 32; j++)

Binary search not working for n = 1, 2

This is my code for binary search, and n = no of elements in array
// Binary Search
// BUG: not working for n = 2
#include <iostream>
int main() {
const int n = 1;
int newlist[n];
std::cout << "Enter " << n;
std::cout << " elements in increasing order:\n";
for( int i = 0; i < n; ++i ) {
std::cin >> newlist[i];
}
int pos = 0, num;
std::cout << "Enter number:\n";
std::cin >> num;
std::cout << '\n';
int imin = 0, imax = n-1;
int imid = (n - 1)/2;
for( int i = 0; i < n; ++i ) {
imid = (imin + imax) / 2;
if( newlist[imid] == num ) {
pos = imid;
}
else if( newlist[imid] < num ) {
imin = imid+1;
}
else {
imax = imid-1;
}
}
if( pos != 0 ) {
std::cout << "Found at " << pos+1;
}
else {
std::cout << "Not found!\n";
}
return 0;
}
It does work for n > 2, but fails to give correct output for n <= 2, ie, gives Not found! output even for elements that were found.
I think one way would be to have a separate implementation for n <= 2, but that will become cumbersome! Please help.
Set your pos operator to -1 rather than 0. 0 represents your first index and since you output that the element has not been found for pos == 0 condition, your code is failing. You should set pos to -1 initially and check that itself for not found condition, if an element is found at pos = 0, that means the element exists at the first index.
First pos equal to 0 is correct value. Therefore set pos to -1 at the beginning and compare to -1 (or more commonly >= 0) when checking whether it was found.
Secondly, there are few items that should be changed because right now it's not that much binary search:
There is no reason to initialize mid before the loop, it's just temporary variable with the scope in loop block.
The condition for exiting the search is min > max, you don't need any additional counter, as it would run the loop always n times even if the value didn't exist. So change to while (min <= max) { ...
Last but not least, once you find the item, exit the loop immediately by break statement.
I don't think a for-loop is the control structure to go for here, because you want to finish when you've either found the correct item or when imin and imax are non-sensical.
In the implementation given, you don't even stop the loop when you have found the item and just confirm the found item "n-(number of iterations until item was found)" times.
Furthermore, with C++ arrays and vectors being 0-based, having position == 0 as the marker for "not found" is a bad idea; you could instead use an item from http://en.cppreference.com/w/cpp/types/numeric_limits, or n (since the indices go from 0 to n-1).
In theory, you could use pointer arithmetic to make your array 1-based, and I am assuming you haven't; I wouldn't recommend it. However, you're code snipped is missing the actual definition of the list.

Implementing a prime number counter

For some reason, my last prime(int prime) isn't showing up at the end. Any clue ?
fyi: primeEval stands for a flag, if the loop ends && primeEval==2, the number is actually a prime number. qty stands for quantity of primes counted.
int main(){
long primeEval=0,prime=0,qtyprime=0;
time_t timerr=(time(NULL)+10);
for (int i = 2; time(NULL)!=timerr; i++) {
for (int j = 1; j <= i; j++) {
if((i%j)==0 && primeEval<2){
primeEval++;
if (i==j && primeEval==2) {
qtyprime++;
prime=i;
primeEval=0; // Resets for the next number 'i'
}
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}
New Answer:
With the change in your code you will now loop through all number. The problem with it now is that once you find a non prime number you will never reset primeEval and because of that you will never capture another prime number If you change your code to the following it will work
int main()
{
long primeEval = 0, prime = 0, qtyprime = 0;
time_t timerr = (time(NULL) + 10);
for (int i = 2; time(NULL) != timerr; i++) {
for (int j = 1; j <= i; j++) {
if ((i%j) == 0){
primeEval++; // incmrent factor
}
// if we are at the end and have 2 factors then we are prime
if (i == j && primeEval == 2) {
qtyprime++;
prime = i;
primeEval = 0; // Resets for the next number 'i'
}
// if we reach the end with more than 2 factors reset and go to the next number
if (i == j && primeEval > 2) {
primeEval = 0; // Resets for the next number 'i'
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
cin.get();
return 0;
}
I would also suggest you look at Which is the fastest algorithm to find prime numbers? to find some more efficient ways to get prime numbers.
Old Answer:
In your code you have:
for (int i = 2; time(NULL)!=timerr; i=+2)
So when you start checking from primes you start with 2 which is prime. Then you increment i by 2 so the next number you check is 4 which is an even number. All even numbers are not prime except for 2. Since you are always adding 2 you will always have an even number so the only prime number you will find is 2.
You have different issues:
for (int i = 2; time(NULL)!=timerr; i=+2) {
Here the syntax is just wrong: it must be i+=2, not i=+2, otherwise you will keep setting i to +2 and testing whether 2 is prime.
Then, as others have pointed out, why are you increasing i by 2? If you want to optimize the search, you should increase j by 2, not i! And j should in any case start from 2 (or, given your approach, from 1), and then you should try j = 3 and then you can increase j by 2 without the risk of skipping some important divisors.
Then, you reset primeEval to 0 only if you find a prime. If you test a number i that is not prime, primeEval stays at 2 and you'll never get into the block again.
So the final code could be:
#include <iostream>
using namespace std;
int main(){
long primeEval=0,prime=0,qtyprime=0;
time_t timerr=(time(NULL)+10);
for (int i = 2; time(NULL)!=timerr; i++) {
primeEval=0;
for (int j = 1; j <= i; j++) {
if((i%j)==0 && primeEval<2){
primeEval++;
if (i==j && primeEval==2) {
qtyprime++;
prime=i;
primeEval=0; // Resets for the next number 'i'
}
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}