After fiddling around with the Collatz Conjecture model I made in Mathematica, I realized that it can be used to map natural numbers to special coordinates - Collatz Coordinates. These coordinates would consist of two parts: A list of "turns" and a "length".
Turns: We see that in a graph with the properties described by Collatz produces a new series of x*2^n for every x that is uneven. Therefore, every time a number is reached one can choose to take the turn or continue on the regular 2^n pattern. The actual turn coordinate that is added to the list is a number. If you took the x-th turn in the current 2^n pattern (starting with x=0), x is added to the end of the list. For example, to get to 13, you take the 0th turn and then the 1st turn.
Length: Once you've found the pattern in which your number lies (taking all the turns), the number you are mapping to Collatz Coordinates can only be on a 2^n pattern. n is the length.
Example:
13 is mapped to: {0,1,0}
21 is mapped to: {1,1}
32 is mapped to: {5} (there are no turns to take here)
I - having turned into the Mathematica fan that I am - wanted to go on right away with writing a Mathematica function to find Collatz Coordinates and to get the number back. I - not being really proficient with using Mathematica - quickly gave up.
So I made an horribly failed attempt at doing it with C++. (Note: This next code is horribly inefficient. The cout's are only there because I had some loop problems and wanted to see the output directly.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
#include <vector>
#define EVEN(x) (!(x&1))
using namespace std;
void CollatzCoordinates(unsigned x)
{
cout << x << ": ";
std::vector<unsigned> out;
unsigned n = 0;
while(EVEN(x)){x/=2;n++;}
out.push_back(n);
x=(3*x+1)/2;
unsigned z=0;
while(x!=1 && x!=2 && x!=4 && x!=8)
{
if(!((x-1)%3)) z++;
if(EVEN(x)) x/=2;
else {out.push_back(z); z=0;x=3*x+1;}
}
// PRINT
for(unsigned i=0;i<out.size();i++) cout << out[i] << ((i!=out.size()-1)?" - ":"");
cout << endl << flush;
// END_PRINT
}
|
Do note that the list has to be inverted after the process.
However, every time I execute this code, it seems to throw away a turn. Specifically, it throws away any turn on 2^n. (like 16->5 or 64->21) It also seems to have some strange outputs on other coordinates.
I've worked on this code for God knows how much too long and can't seem to find the problem. Do any of you?
Thanks in advance.
EDIT: Fixed a little typo.