So, I was bored, and decided to make something completely random, then I came across the collatz conjecture: start with any positive number, and if it is even, devide by two. If it is odd, multiply by three and add one. When repeating this, you will end at the number one. So I made this code:
//Collatz Conjecture by Lucas Knook
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
long long n;
cin >> n;
cout << setw(5) << n;
while(true){
if(n % 2 == 0 && n != 1){
//is even
cout << " E" << endl;
n /=2;
cout << setw(5) << n;
}
else if(n != 1){
//is odd
cout << " O" << endl;
n = n * 3 + 1;
cout << setw(5) << n;
}
else break;
}
cout << " O" << endl << endl << "end loop";
return 0;
}
I am still learning c++ (I just completed the sololearn course, and I am about to get the "C++ for dummies all-in-one" book), but I think this is a good start for me, and it works.
There is just one little problem: If I use big numbers, it does stop at one, and gets the odd and even right, but...
Look at this first part of the output when entering
"1000000000000000000000000" :
9223372036854775807 O
9223372036854775806 E
4611686018427387903 O
-4611686018427387906 E
-2305843009213693953 O
-6917529027641081858 E
-3458764513820540929 O
8070450532247928830 E
4035225266123964415 O
-6341068275337658370 E
-3170534137668829185 O
8935141660703064062 E
4467570830351532031 O
-5044031582654955522 E
-2522015791327477761 O
-7566047373982433282 E
-3783023686991216641 O
7097673012735901694 E
3548836506367950847 O
-7800234554605699074 E
Ehm, that's a bit weird, isn't it? (don't look at the line breaks, it is perfectly stacked, it just doesn't show here, because I copied the output)
Can someone please explain me why this is happening and how to fix it?
You've exceeded the limits of long long integer values. The first value in your output is truncated to be much smaller than your input, then when you get to 4611686018427387903 it's multiplied by 3, since it isn't even. That's when it overflows the type and wraps around into negative values. You'll need to use a BigInteger library, like TTMath.
Basically as other people pointed out you don't check for overflow. But I would like to point out different thing, your code is still not valid as you don't check if you got into endless loop, when multiplication and division sequence generates the same numbers, your while will never end.
This is correct code with simple overflow detection:
#include <iostream>
#include <unordered_set>
bool colatazConjecture(int n) {
std::unordered_set<int> localComputed;
int newN = 0;
while (n != 1) {
if (!localComputed.emplace(n).second) {
throw "Cycle detected";
}
newN = n;
if (n & 0x1) {
newN = 3*n + 1;
if (newN <= n) {
throw std::overflow_error("Overflow for " + std::to_string(newN));
}
} else {
newN >>= 1;
}
n = newN;
}
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Tried several times yet still didnt manage to find my mistake: here is my program. i need to find the odd numbers from 1 and integer x and find the sum of them cubed.
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int x;
int i = 1;
int result;
cout <<" Enter the value for n" << endl;
cin >> x;
while (i >x)
if (i%2 == 0) {}
else {
result += pow(i,3);
i++;
}
cout << "The sum of odd integers cubes from " << i << " to " << x << "= " << result << endl;
return 0;
}
Minimally, you should change the compare in while
from
while (i > n)
to
while (i <= n)
There a many numbers where i will be greater than the number entered, n.
You didn't add in your curly brackets for the while loop.
while (i > x)
if (i%2 == 0) {}
needs to be:
while (i > x){
if (i % 2 == 0) {}
}
Plus what are you doing inside of that if statement? You should decrement x, to find if each number is odd.
Plus, your program ends early because i is 1 and if the user enters a number above 1, your while loop won't even run. You're telling the while loop to run ONLY when i is larger than x. Try changing it to less than:
from:
while (i > x){
to:
while (i < x){
Plus you're not doing anything with x. You want to decrement x, not add i. Although, I would recommend using a do-while loop. ( a dowhile loop does one iteration first before incrementation)
do{
if (x % 2 == 0) { // if the remainder of x/2 is 0, do this
x--;
cout << "Equal: " << x << endl;
}
if(x % 2 != 0) { //if the remainder of x/2 is not 0, do this.
temp = pow(x,3);
//you don't want to take the power of the added sum,
//you were taking the power 3 of x which was being added to.
//you want to add the sums of each power. So here we have temp, a
//temporary variable to store your addends.
result = result + temp;
cout << "Not equal, temp:" << temp <<endl;
cout << "Result: "<< result << endl;
x--; //you didn't have a decrement, you need to bring x eventually down to i if you want the loop to end, or even look through all of the numbers
}
}
while (i < x);
//You have to have this semi colon here for the compiler to know its a do-while.
cout << "The sum of odd integers cubes from " << i << " to " << userVar
<< " = " << result << endl;
return 0;
}
note: if-else statements are for flow control, its like true and false, one or the other, so that your data will flow somewhere. I used two if statements because I want to have complete control over the flow.
note2: It's ok to use:
using namespace std;
at first, but eventually you want to start learning what library each command is using. When you get into more complex programming, you start using commands from different libraries than the standard one.
I am trying to create a program to print first 200 elements following a specific numerical series condition which is
1-1-3-6-8-8-10-20
But instead of showing, just 200 elements is showing 802. I assume is because of the code inside the for loop. I have hours thinking on how to reduce that code to the job and I cannot think anything else. I am getting frustrated and need your help.
The exercise is on the code comments
//Print the following numerical series 1-1-3-6-8-8-10-20 until 200
#include <stdafx.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int Num1=200, z = 0, x = 1, y = 1;
cout << "\n\n1,";
cout << " 1,";
for (int i = 1; i <= Num1; i++)
{
z = y + 2;
cout << " " << z << ","; //It will print 3
z = z * 2;
cout << " " << z << ",";//It will print 6
z = z + 2;
cout << " " << z << ",";//It will print 8
z = z;
cout << " " << z << ",";//It will print 8
y = z;
}
cout << "\n\n";
system("pause");
return 0;
}
You're looping 200 times, and each time you loop, you're printing out 4 different numbers. You're also printing twice at the start so thats 2 + 4 * 200 = 802, which is where your 802 number output is coming from.
I assume is because of the code inside the "for" loop but I've hours
thinking on how to reduce that code to the job and I cannot think
anything else. I'm getting frustrated and need your help.
So you basically wanna simplify your code. Which can be done by noticing the repetitions.
There you can find only two types of change in the series; either a +2 or x2 with the previous element.
In each iteration this can be achieved by:
If reminder i%4 == 1 or i%4 == 3, need an increment of 2 (assuming 1 <= i <= MAX)
If reminder i%4 == 0, nothing but a multiplication of 2.
When you do like so, you can simply neglect, printing of first two ones and other complications in the total numbers in the series.
Also not that, you are trying to get 200 terms of this series, which increases in each step very fast and exceed the maximum limit of int. Therefore, long long is needed to be used instead.
The updated code will look like this:
#include <iostream>
typedef long long int int64;
int main()
{
int size = 200;
int64 z = -1;
for (int i = 1; i <= size; i++)
{
if ((i % 4 == 1) || (i % 4 == 3)) z += 2;
else if (i % 4 == 0) z *= 2;
std::cout << z << "\n";
}
return 0;
}
See the Output here: https://www.ideone.com/JiWB8W
I have a problem that is asking for me to write a C++ program using for loops with less than 3 “cout” statements in your code to print the following pattern (ignore the pipes, the asterisks wouldn't appear without them):
|*
|***
|*****
|*******
|*********
|*********
|*******
|*****
|***
|*
This is my code I used for a fibonacci generator and I feel like it might be similar. I am able to print the "*" symbol but not in horizontal lines. What I need most help with is reversing the output. As in if given number n, I want the series to go n numbers into the series and then back down to 0.
#include <iostream>
using namespace std;
int main()
{
int y = 1, sum = 1, n;
cout << "Enter the number of terms you want" << endl;
cin >> n;
cout << "First " << n << " terms are :- " << endl;
for (int x = 0; x < n; x++) {
cout << "\n" <<endl;
for (int i = 0; i < sum; i++) {
cout << "*" << endl;
}
sum = y + 2;
y = sum;
}
}
It seems this is a homework, so I give some hints instead of a full solution.
For printing the *s in one line, please note that << endl will end the line in the output, i.e. print a line break. (The same does << "\n" by the way.) Not every cout statement has to have an << endl at its end.
For reversing the fibonacci sequence, once you have the last number in the variable sum, just do the reverse computation (i.e. subtraction). This could be done in a second set of loops, however, since you should not use cout statements too often, you better reuse the same loop by using some additional variable holding the current state (i.e. if you are counting up or down) and using an if to decide which computation to do. (I read the requirements such that only the cout statements for printing the pattern count to the "less than three" = 2)
I am new to dynamic programming and coded a program to find longest common subsequence using dynamic programming however to understand DP better I thought it would be a good idea to print results in each if-else condition in my recursive function, however that output is making no sense to me.
For instance, the first output is "Now m and n both are 0", but why? Shouldn't it be "Last characters B and B are equal " ? I'm sure compiler is using some logic which I'm not aware of, but I really want to know what is actually happening!
#include<iostream>
#include<cstring>
using namespace std;
int max(int a, int b)
{
return (a > b) ? a : b;
}
int lcs(char *X, char *Y, int m, int n)
{
if (m == 0 || n == 0)
{
cout << " Now m and n both are 0" << endl;
return 0;
}
if (X[m - 1] == Y[n - 1])// last character same
{
cout << " Last characters " << X[m - 1] << " & " << Y[n - 1] << "are equal " << endl;
return (1 + lcs(X, Y, m - 1, n - 1)); // add 1 + computer for rest
}
else
{
cout << " Last characters " << X[m - 1] << " & " << Y[n - 1] << "are unequal " << endl;
return max(lcs(X, Y, m, n - 1), lcs(X, Y, m - 1, n));
}
}
int main()
{
char X[] = "AGGTAB";
char Y[] = "GXTXAYB";
int m = sizeof(X)-1;
int n = sizeof(Y)-1;
cout << " LCS length is " << lcs(X, Y, m, n) << endl;
int a;
cin >> a;
}
If you put a break point in the beginning of the lcs function you'll see that indeed the first output is Last characters B & Bare equal.
I think the reason you're not seeing that in the terminal is because of line limitation in the output. If you need any help on tracing add comment and I'll edit my post to cover the trace.
Your Program is working correctly,although some problems are still there.
1) Checking for m and n should be less than 0,not equal to it as it should go from size_of_array - 1 to 0.
2)Add a space after and before printing a value in std::cout.
For example, in your output : Last characters G & Gare equal should be actually Last characters G & G are equal
3) It is NOT Dynamic Programming Implementation. This is brute force as you may know.
Whilst working on a personal project of mine, I came across a need to divide two very large arbitrary numbers (each number having roughly 100 digits).
So i wrote out the very basic code for division (i.e., answer = a/b, where a and b are imputed by the user)and quickly discovered that it only has a precision of 16 digits! It may be obvious at this point that Im not a coder!
So i searched the internet and found a code that, as far as i can tell, uses the traditional method of long division by making a string(but too be honest im not sure as im quite confused by it). But upon running the code it gives out some incorrect answers and wont work at all if a>b.
Im not even sure if there's a better way to solve this problem than the method in the code below!? Maybe there's a simpler code??
So basically i need help to write a code, in C++, to divide two very large numbers.
Any help or suggestions are greatly appreciated!
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std; //avoids having to use std:: with cout/cin
int main (int argc, char **argv)
{
string dividend, divisor, difference, a, b, s, tempstring = ""; // a and b used to store dividend and divisor.
int quotient, inta, intb, diff, tempint = 0;
char d;
quotient = 0;
cout << "Enter the dividend? "; //larger number (on top)
cin >> a;
cout << "Enter the divisor? "; //smaller number (on bottom)
cin >> b;
//making the strings the same length by adding 0's to the beggining of string.
while (a.length() < b.length()) a = '0'+a; // a has less digits than b add 0's
while (b.length() < a.length()) b = '0'+b; // b has less digits than a add 0's
inta = a[0]-'0'; // getting first digit in both strings
intb = b[0]-'0';
//if a<b print remainder out (a) and return 0
if (inta < intb)
{
cout << "Quotient: 0 " << endl << "Remainder: " << a << endl;
}
else
{
a = '0'+a;
b = '0'+b;
diff = intb;
//s = b;
// while ( s >= b )
do
{
for (int i = a.length()-1; i>=0; i--) // do subtraction until end of string
{
inta = a[i]-'0'; // converting ascii to int, used for munipulation
intb = b[i]-'0';
if (inta < intb) // borrow if needed
{
a[i-1]--; //borrow from next digit
a[i] += 10;
}
diff = a[i] - b[i];
char d = diff+'0';
s = d + s; //this + is appending two strings, not performing addition.
}
quotient++;
a = s;
// strcpy (a, s);
}
while (s >= b); // fails after dividing 3 x's
cout << "s string: " << s << endl;
cout << "a string: " << a << endl;
cout << "Quotient: " << quotient << endl;
//cout << "Remainder: " << s << endl;
}
system ("pause");
return 0;
cin.get(); // allows the user to enter variable without instantly ending the program
cin.get(); // allows the user to enter variable without instantly ending the program
}
There are much better methods than that. This subtractive method is arbitrarily slow for large dividends and small divisors. The canonical method is given as Algorithm D in Knuth, D.E., The Art of Computer Programming, volume 2, but I'm sure you will find it online. I'd be astonished if it wasn't in Wikipedia somewhere.