Skip to main content

Problem 14: projecteuler.net: Matlab: Largest Collatz Sequence

Problem

The following iterative sequence is defined for the set of positive integers:


n  n/2 (n is even)
n → 3n + 1 (n is odd)

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

Using the rule above and starting with 13, we generate the following sequence:
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
Solve the above problem using Matlab

Solution

Collatz sequence has already been defined in the problem section. If you want to know more about collatz sequence then click on the links below:
The solution is simple and we will only use the basics to solve this problem. Please have a look at the program(s) to get an idea of the program. If you are not able to understand the program then go to the explanation section below the program section. If you still can't understand the program after reading the explanation section then visit the links below to learn the basics behind the program(s).
6) rem function in Matlab (Remainder after division)
7) logical function in matlab
8) Functions in Matlab
9) Vectors in Matlab

Don't get scared of all these links, these are just for the reference. First have a look at the program and if you don't understand, then go to explanation section and then, if you still don't understand, then select the only link which you didn't understand in the program have a look at them and there you go, you will understand the program easily.

It should be noted here that this program has a unique characteristic: This program uses both for loop and the while loop or combination of both the for and while loop to accomplish the task.

Program

We can write the program in two ways. But out the two programs one program execution time is far less than the other. Try both the programs and comment the program number which has the less execution time. All the Matlab files has been attached at the end of each program. You can download them for free.
Program 1:

function result = even(n)

%This function will return whether the number is even or odd

if rem(n,2) == 0
    result = logical(1);
else
    result = logical(0);
end

You can download the above program in matlab file format for free from here: even.m

function result = size_collatz(x)
%this function will give the length of the collatz sequence of a given
%number using the vector
vec = [x];
while x~= 1
    if even(x)
        x = x/2;
    else
        x = (3*x)+1;
    end
    vec = [vec,x];
end
result = length(vec);
You can download this file as matlab file format for free from here: size_collatz.m

We can also write the above program (size_collatz) without using the vectors as follows:

function result = size_collatz2(x)
%this function will give the length of the collatz sequence of a given
%number
count = 0;
while x~= 1
    if even(x)
        x = x/2;
        count = count+1;
    else
        x = (3*x)+1;
        count = count+1;
    end
end
result = count+1;
You can download the above file in matlab file format for free from here: sizecollatz2.m

And the final main script for finding the number which produces the largest chain under one million is as follows:


tic;
largest = 1000000;
for i = 1:999999
    if size_collatz2(i)>size_collatz2(largest)
        largest = i;
    end
    disp(largest);
end
toc
Download the above script in Matlab file format for free from here: largest_collatz.m

To run your program you can use the scripts combinations as follows:

Combination 1
even.m
size_collatz.m
largest_collatz.m

Combination 2
even.m
size_collatz2.m
largest_collatz.m
Both of the combinations in the program 1 give results approximately at same timing. But the difference only occurs when you will use the program 2.

Program 2:


tic;
count1 = 0;
for i = 1:1000000
    x = i;
    count = 0;
    while x~=1
        if rem(x,2) == 0
            x = x/2;
            count = count+1;
        else
            x = 3*x+1;
            count = count+1;
        end
    end
    if count>count1
        largest = i;
        count1 = count;
    end
end
disp(largest)
toc
You can download the above program in Matlab file format from here: largest_collatz2.m

Once again, run the program for yourself and comment the best program you think which is giving the fastest results.

Explanation

I will explain this post program wise so that there won't be any confusion for you.
Program 1
even.m
In this program I have used the if else statement in combination with the rem function to check if the given input number is divisible by 2 or not. If the number is divisible by 2 then the number is even and thus the result returned is logical(1) or else true. Else if the number is not divisible by two then the result is logical(0) meaning false or not an even number.
size_collatz.m
Here in this function we have created a vector which stores the numbers of the collatz sequence. To understand this program let us consider the example of input as 13, then
During at first the vec value will be [13], now while loop starts as the value of 13 is not equal to 1. In the while loop the number is not even so the else statement is invoked and the value of x is changed from 13 to 40. After that 40 gets stored in the vec vector and now the vector is [13,40]. In the next iteration as the condition is satisfied(40~=1), the if statement is invoked because the 40 is even. Now the value of the x is changed from 40 to 20 and the same gets stored in the vec. The vec value here is [13,40,20]
And this continues till the end and the result we get is [13,40,20,10,5,16,8,4,2,1].
Finally at the end the length of the vec is calculated and the result is returned for processing in the next program (largest_collatz)
size_collatz2.m
In this function unlike the above function where we will create a vector and find the length of the vector, we will use a counter variable to find the length of the chain directly by increasing the counter variable for every iteration.
So coming to the program, I have created a count variable and initiated it to zero. To understand the program easily let us consider the example of 13, now,
13 is not an even number and thus the else statement is invoked and the value of x changes to 40 and the counter variable 'count' increases to 1, in the next iteration the value of x changes from 40 to 20 and the counter variable changes its value to 2 and this iterations continue till the value of x changes to 1 and thus here in this example,the counter variable changes to 9, Finally after all the iterations the 1 is added to the value of the count variable because in the starting of the program we haven't calculated the value of the 13(in this example). Thus the result is 10 and this is returned for further processing.
largest_collatz.m
In this program initially we have created tic to start the clock so that at the end of the program where we have toc to end the clock and thus we can find the time of execution.
we have created largest = 1 million
Now the for loop starts and the if statement checks if the size of the collatz sequence of the collatz of the iterator is greater than the size of the collatz of the largest then the largest is replaced with the iterator variable, so that at the end of all the iterations the largest will be the answer. This can be assumed as if you are larger than me then I have to go out, if some other person is larger than you, you have to go out and give the place, if some other is larger then that person will stay and other will go out. And similarly the larger will stay and others will go out. "Survival of the largest!!"
Finally at the end of the for loop the toc gets executed and the value of the largest and the time of execution is given as output.
largest_collatz2.m
This program is very simple. In this program instead of having different functions, I have combined all the programs in one script and the result is largest_collatz2.m . Now lets us see the program:
First the tic is started to start the stop watch.
count1 = 0
In the for loop the value are iterated from 1 to 1 million.
Now a variable 'x' is created to store the value of i.
count is initiated to 0;
A while loop checks the conditions and the count variable is increased for every iteration until the value of x is 1. And after the while loop iterations are over an if statement is initiated to check is the value of the previous count(count1) is greater than the count of the present variable(count) and if it is greater then the largest is the i(iterator).
"The same principle of the survival of the largest applies here".
Finally the value of largest is displayed using the disp.
And the toc is initiated to stop the stopclock and the the value of the time of execution is also displayed.

I have tried to explain the program in a easy to understand fashion. If you have any doubt or didn't understand the program then please contact me so that it will be useful for you and also others. You can contact me from here: contact me

References


All the above programs have been high lighted using hilite.me
The problem has been taken from projecteuler.net from here: problem 14-project euler

Keywords: even number,odd number, matlab functions, projecteuler.net, size of collatz, largest collatz less 1 million

Popular posts from this blog

Making a quiz web app with python and flask

Edit : When you are creating a web app with h tml templates, then y ou will have to sa ve the html file in templates folder in the Current Wor ki ng Directory( CWD). If you save the file in the C W D directl y you will get a TemplateNotFound error. Thank you Udhay for pointing it out.   In this post we will create a quiz website using python . I will be using the flask framework . After reading this tutorial you will learn form submission , flask templates , python code in flask templates , shuffling the questions and options with the random module and few others.  Please note that this tutorial is not big as it seems to be. Some of the code has been rewritten to maintain consistency and also font size is somewhat big so that your eyes won't get stressed reading this tutorial. Also the content has not occupied the full width of the page. In this tutorial I am assuming that you are having a very basic understanding of the flask framework . Please refer the documentation

Problem 11 Project Euler Solution with python

Largest product in a grid In the 20×20 grid below, four numbers along a diagonal line have been marked in red. 08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07

Problem 60 Project Euler Solution with python

Prime pair sets The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property. Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime. This problem is j u st a brute force problem. If you have come here because you don't know the limit upto which you will h ave to gener ate the prime numbers t hen go ahe ad and t r y with 10,000 . When I first start ed solving the problem I chose 1 million(beca use most of the problem s on project E uler have this limit ), but it took very long for the computer to fin d the solution. After searching on the internet then I found many people choosing 10, 000 so I have changed my in put f rom 1 million to 10000 and the output was f ast. He