Starting with a number, the following is called the Collatz rule:
If the number is odd, multiply by 3 and add 1.
If the number is even, divide by 2.
The Collatz conjecture suggests that when you keep doing this, you will always reach 1 eventually.
For example, if you start with 7, you reach 1 in 16 steps: 7 → 2 2 → 1 1 → 3 4 → 1 7 → 5 2 → 2 6 → 1 3 → 4 0 → 2 0 → 1 0 → 5 → 1 6 → 8 → 4 → 2 → 1 . However, 7 is not the only number that requires 16 steps. What is the total number of positive integers which require exactly 16 steps to reach 1 for the first time ?
Note : This problem is intended to have a coding solution.
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
cool you did it with one loop and used the fact that x = 6 k + 4 implies ( x − 1 ) / 3 = 2 k + 1 is odd
The largest possible value to reach 1 in 1 6 steps is 2 1 6 = 6 5 5 3 6 , so we do not need to check higher. 6 5 5 3 6 will keep halving a total of 1 6 times until it reaches 1 , and any larger value will need to halve at least 1 7 times.
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 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
The 2 9 integers are 7 , 4 4 , 4 5 , 4 6 , 2 7 2 , 2 7 6 , 2 7 7 , 2 8 0 , 2 8 2 , 3 0 0 , 3 0 1 , 3 0 2 , 1 5 3 6 , 1 6 6 4 , 1 6 9 6 , 1 7 0 4 , 1 7 0 6 , 1 8 0 8 , 1 8 1 2 , 1 8 1 3 , 1 8 1 6 , 1 8 1 8 , 1 0 2 4 0 , 1 0 7 5 2 , 1 0 8 8 0 , 1 0 9 1 2 , 1 0 9 2 0 , 1 0 9 2 2 , and 6 5 5 3 6 .
Please post your java code, I will make sure that it renders properly. (Using my moderator powers)
Log in to reply
Just fix the first couple of lines.
Log in to reply
fixed. Is this fine?
Hi! hope you remember. Can you help me with a bit of coding?
By hand I also got 10880 and 10922. They seem to work, or did I make a mistake?
Log in to reply
You can see that those are correct according to my solution, but there are also more.
I tried to generate the list backwards using recursive function with this rule.
With this, I generate a function as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
yeah, this seems like a simple, efficient method. Interestingly, I arrived at that exact same condition, in line 9. I found it to somewhat ugly, but I have no clue how it could be made simpler?
I tried by hand, working forward from 1. I only got 23, some of which were wrong. I am not a computer! There are some interesting patterns, e.g. multiples of 3 don't branch. The tree starts 1,2,4,8,16 before branching to 5 and 32. 5 goes to 10, which branches to 3 and 20. The 3 branch just continues to 768. I wonder if there is a nice analytic solution?
Log in to reply
The whole mystery of the Collatz conjecture lies in the fact that we don't know if there is an analytic solution.
As you mention the Collatz tree, this website allows you to generate quite a nice one. By setting the orbit length to 1 7 , you can get all the required numbers.
Wikipedia - Collatz conjecture
https://oeis.org/A005186
Simple Python Solution:
collatzNumbers = [[1]]
def backCollatz():
l = []
for n in collatzNumbers[-1]:
l.append(n*2)
g = ((n-1)/3.0)
if g % 2 == 1 and not g == 1:
l.append(int(g))
collatzNumbers.append(l)
# print a
for i in range(16):
backCollatz()
print len(collatzNumbers[-1])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
A simple approach is the recursive approach. Considering all the integers as nodes in a graph and pointing an integer to the next integer by the Collatz rule, we get a directed acyclic graph. We backtrack along this graph to find the number of nodes that are a "Collatz distance" of 16 from the node 1.
We note that, by the Collatz rule, we can always get n from 2 n since 2 n is always even. We can also get n from 3 n − 1 if said number is an integer and is even, which happens only when n ≡ 4 ( mod 6 ) . We do not consider this rule when n = 4 since it loops back to 1.
1 2 3 4 5 6 7 8 9 10 11 |
|
The program terminates quickly with the answer 29 .
I used java:
public static void main(String[] args) {
ArrayList<Integer> a = new ArrayList<Integer>();
for(int i = 5; i <= Math.pow(2, 16); i++) {
if(collatz(i, 0) == 16) {
a.add(i);
}
}
System.out.println(a.toString());
System.out.println(a.size());
}
public static int collatz(int num, int steps) {
if(num == 1) {
return steps;
} else if (steps > 16) {
return 0;
} else if (num % 2 == 1) {
return collatz(3*num + 1, steps + 1);
} else {
return collatz(num / 2, steps + 1);
}
}
My solution is in python. I know that the biggest number that requires 16 steps is 2^16 = 65536, all the numbers bigger than 65536 will need more than 16 steps, so my program tries all the numbers from 7 to 65536. When the number is odd, I do two steps in one, because after have multiplied by 3 and added 1, the number is even, and the next step is always to divide by 2.
All the numbers (except 4, 2 and 1 obviously) finish their series with 16, 8, 4, 2, 1. It's because there is no integer n, such that n * 3 + 1 = 8, and the only solution for n * 3 + 1 = 4 is 1. Therefore, the programm stops at 8 and not at 1, to save some time, and the number of steps must be 13. The programm does not stop when the number equals 16, because if the number arrives at 5, it would directly reach 8 and skip the verification.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Here's my code using Dev C++
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 |
|
After running the program, it should look like this:
(The reason why 6 5 5 3 6 is the highest number to test for is because it will either divides 2 or multiplies by 3 then add 1 so clearly, if it's something bigger than 6 5 5 3 6 , it will eventually hit odd numbers and get multiplied by 3 unless if it's a power of 2 .)
Running the code, there should be 2 9 numbers as listed, hence the answer is 2 9 .
You can try pasting the code here. I will help you format it correctly if necessary.
Log in to reply
Actually just tell me how to insert the "coding" thing. I'll edit them later. Thanks.
Moderator's edit:
1 |
|
Log in to reply
I have edited your last comment to explain how to insert code. You can click edit and see for yourself. Read the Formatting Guide
2^16=65536 is the largest value which would take 16 steps. Any larger number would take more steps.
If a number already took more than 16 steps then it slips out of the nested for loop. If a number reaches 1, also slips out of the nested for loop. And each time a number slips start_num increases by 1...
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 |
|
Output :
1 2 3 4 |
|
Efficient!!!!
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 29 30 31 32 33 34 |
|
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 29 30 |
|
Python straightforward solution:
1 2 3 4 5 6 7 8 9 10 |
|
Please someone tell me how to defeat this strange formatting system, cause I fail for some reason...
Explanation of Formatting system
Log in to reply
Thx. I think it should be noted in the wiki page that a couple of empty strings should be kept before the start of the code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
a n s = 2 9
By George Coyne
Here is a solution in python but I cannot figure out how to get line numbers
xMax = pow(2,16) # Don't need to check numbers > 2^16
cnt = 0
solutions = []
for x in range(1,xMax+1):
x0 = x
steps = 0
while steps < 16 and not (x == 1) and (x <= xMax):
if x % 2 == 1:
x = 3 * x + 1
else:
x = x // 2
steps += 1
if x == 1 and steps == 16:
solutions.append(x0)
cnt += 1
print("There are {0} solutions: {1}".format(cnt, solutions))
Output: There are 29 solutions: [7, 44, 45, 46, 272, 276, 277, 280, 282, 300, 301, 302, 1536, 1664, 1696, 1704, 1706, 1808, 1812, 1813, 1816, 1818, 10240, 10752, 10880, 10912, 10920, 10922, 65536]
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 29 30 31 32 33 34 35 36 37 38 |
|
Mathematica one liner:
Count[Array[If[#>1,#0@If[OddQ@#,3#+1,#/2]+1,0]&,2^16],16]
In Mathematica, the code below return 29 (with memoization):
collatz [ n$_$ ] := collatz [ n ] = If [ n = = 1 , 0 , If [ Mod [ n , 2 ] = = 0 , collatz [ n / 2 ] + 1 , collatz [ 3 n + 1 ] + 1 ] ] ; \ Length [ Select [ Table [ n , { n , 2 1 6 } ] , collatz [ # ] = = 1 6 & ] ] )
Gotta love ES6.
I solve it backwards and show the steps each one takes at the end. The numbers make a neat little gradient at the end.
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 29 30 31 32 33 34 35 36 37 |
|
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
*counter: 29
The greatest integer that would have n steps is 2 n (in which case every step would be even, so every step decreases). The next greatest possible value with n steps is 3 2 n − 1 − 1 . To obtain this, you could think about it like this: there are two ways to reach one value (dividing a certain value in half, or multiplying another certain value by 3 and adding 1). To get the highest values, you need to find the two ways to reach 2 n − 1 , which takes exactly n-1 steps to get to 1. The first way is to multiply this by 2, giving us our greatest value 2 n . The other way is subtracting 1 and dividing by 3, giving us 3 2 n − 1 − 1 . The latter value isn't always an integer, but the second greatest integer can't be greater than this value. This is helpful since we know we can stop an iterating program once we've reached this value, and simply append 2 n to the answer list.
I wrote a Python program that took in a value n, which is the number of steps you are trying to compute for (in this case, 16). It would loop for integers from 1 to 3 2 n − 1 − 1 + 1 (the plus 1 is so that Python includes this value). For each integer, it would keep track of the steps taken according to the Collatz rule, putting the values in a list. If the length of the list exceeded n, it would move on to the next integer. If the list reached the value 1, Python checks if the length of the list is n. If it is, it appends the starting value to a separate list names "ans". At the end of this loop, I append 2 n since I know this is also a solution, then I print the length of the ans list.
def hail(n): # n is number of steps to reach 1
ans = []
for a_0 in range(1, int((2**(n-1)-1)/3) + 1): # Tests all integers from 1 to known bound (before 2^n)
out = [] # Lists each step for a starting integer
a = a_0
while a != 1:
if len(out) > n:
out = []
break
elif a%2 == 0: # if even, divide by 2
a = a/2
else:
a = 3*a + 1 # if odd, multiply by 3 and add 1
out.append(a)
if len(out) == n:
ans.append(a_0)
ans.append(2**n)
print(len(ans))
return ans
When ran, and calling the function with 16 as the argument, we get:
>>> hail(16)
29
[7, 44, 45, 46, 272, 276, 277, 280, 282, 300, 301, 302, 1536, 1664, 1696, 1704, 1706, 1808, 1812, 1813, 1816, 1818, 10240, 10752, 10880, 10912, 10920, 10922, 65536]
I just cranked it quickly with AWK , without much pre-thinking of the problem (off-the-cuff simplifications, such as 65536 would be the largest integer that would generate a length of 16.
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 |
|
seq length 16 occurs 29 times
Once you figure out that the largest possible number to reach 1 in 16 steps is 2^16 = 65536 things are pretty easy (I tried up to 30 million before i thought of that).
I used Matlab and the broke the while loop function at 17 steps to not fry my laptop. The script should compute the solution within a second. First, write a function for Collatz which takes in a number k and yield the number of steps required to reach 1 (or rather, how many steps, up to 17, does it take to reach 1).
Then we just need a few lines on another script to run our function from 1 to 65536. I used logical arrays to smoothen the elimination process, thanks to Matlab.
Ta da!
Simple brute-force using Python
def collatz(n):
x = 2
while n != 4:
if n % 2 == 0:
n /= 2
else:
n = 3 * n + 1
x += 1
return x
n = 0
for i in range(5, 2 ** 16 + 1):
if collatz(i) == 16:
n += 1
print(n)
A straight forward (maybe a bit dummy) way to compute this is to check every number up to the largest possible one, which is 2 1 6 .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
The above returns 29, which is the answer !
Problem Loading...
Note Loading...
Set Loading...
I generate the list backward : thus, if for a given number n it takes p steps to reach 1 for the first time, then
it takes p + 1 steps for the number 2 n ;
it takes p + 1 steps for the number 3 1 ( n − 1 ) , provided this is an odd integer. This happens when n has remainder 4 after division by six. Also, we exclude the case n = 4 , because that would simply give us back the number 1.
I decided to use old-fashioned C. The data structure is a simple queue: new numbers are written at position
write
; they are read at positionread
. At any given point, the number of items "on hold" is equal towrite - read
. As soon as we exhaust the numbers that took 15 steps, we know that the remaining values in the queue are all that take 16 steps.Output: