C++ Math and Fun

Introduction

Some people think math is boring, and you have to have something extra in your brain to understand it. In fact, not all branches of mathematics are boring and very tough for a person who does not have a math background. Number theory is one such branch of math that may be very attractive to a normal person without learning lots of stuff.

Number theory is the study the properties of integers; in other words, whole numbers. This is perhaps the oldest branch of mathematics and is also called Queen of Mathematics by the Prince of Mathematics, Gauss, because lots of branches of mathematics are developed to solve the problems of number theory. In fact, there is no need to have lots of math background to start the study of it. To see the beauty of it, however, you have to be familiar with different branches of math. In fact, in the past, number theory was considered pure mathematics because there is no application of it outside the world of math. But, there are lots of applications of it available now, such as cryptography, random number generator, error detection, security, and so on. Still, a fascinating thing about number theory is that there are still lots of unsolveds problem in it. It might be possible that fewer branches of math will be evolved and a few more techniques will be developed to solve those problems.

The whole study of number theory is the beautiful proof of different problems, and solves more complex problems on the basis of existing proofs. It is interesting to note that if any conjecture or assumption is not proved in number theory, it still may have applications in real life. For example, the well-known cryptography algorithm RSA is based on the assumption that it is not easy to find the prime factor of a very large number if it is a multiple of two or more huge primes.

Here, we are trying to implement one very easy, but interesting problem, the Collatz problem, by using different programming techniques. The most interesting thing about this problem is that the algorithm of this problem is not classified for all possible input until now, although it is very simple to state it. This problem is also known as the hailstone problem, 3n+1 problem, Hasse's algorithm, Kakutani's algorithm, syracuse problem, or the Thwaites Conjecture or Ulam's problem. This problem was posed by L. Collatz in 1937.

In ther words, it is a very simple problem. Take any number as an input, and divide it by 2 if the number is even, or multiply by 3 and add 1 if the number is odd. The conjecture is that, no matter which no you take as an input, you will come to 1. However, this is still an open problem and no one can prove it until it is true for all values of n, although it has been checked for quite large numbers through a computer. This might be a challenging task for those who want to solve open problems and gain popularity.

Total the numbers of elements in the sequence until it reaches 1, including input number and 1; this is called the cycle of the sequence of that given input number. For example, if user input 5, the sequence will be something like this:

5 16 8 4 2 1

The cycle of this sequence is 6. This sequence is also called the hailstone sequence.

Algorithm A (Algorithm for 3n+1 sequence)

Okay, now let's come to the implementation side of this algorithm. Here, I tried to do some fun with this simple algorithm and tried to implement it in different programming styles.

No Structured Programming

This is perhaps the first technique of programming the computer, without any procedure or anything else. The most problematic thing about this style is its management and reusability because there is almost no abstraction layer in this style of programming. Therefore, it is quite difficult to handle a large-scale program using this technique.

Structured Programming

Break down the program into small modules (functions), so it will become more manageable and more reusable than the non-structured version. Logically, one function of the program should do the unit work of the algorithm, but it is quite subjective to describe the unit work. This programming style will increase the abstraction level by dividing the problem into small pieces and solving those pieces one by one.

Recursive Programming

Do you know what the meaning of GNU is? GNU stands for "GNU's Not Unix." Doesn't that look strange? The name itself appears in the acronym, and when you try to expand it, GNU will again appear in acronym. This is a simple example of recursion. In other words, a more typical definition may be something like this: "Recursion is a way to specify a process by repeating a means of itself." In programming language context, recursion means a function that calls itself. Typical examples of recursion are factorial, Fibonacci number, Tower of Hanoi, and so forth.

Object-Oriented Programming

Object-oriented programming is a programming style in which you make classes and create instances of those classes, called objects. Technically, a class is a prototype that defines the variables and methods of one kind. This problem is very small, so that you can not get the full advantage of object-oriented programming. This program is technically object based but not object oriented.

Generic Programming

Generic means general or common. Technically, generic programming refers to a program written in such a way that it should work independent of data type. A generic program should work on all data types that satisfy the required concepts use in the program. In C++, a template is used for generic programming.

Template Metaprogramming

Template metaprogramming is the most beautiful programming technique of C++. In this programming style, you use your compiler to do the program's work for you. In other words, it is something like writing a program about a program. In template metaprogramming, you are a using C++ compiler as an interpreter; in other words, the compiler expands the template and generates the code, which can be executed at run time by the compiled code. Execution speed of this program is very fast because the compiler has already resolved it at compile time. Nothing comes without price, and here the price is compilation time. Compilation time of your program may increase drastically; the length of times depends on the nature of the algorithm implemented by using this technique.