Euler Problem: Solution of Problem-4 in C++

Q) A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 * 99. Find the largest palindrome made from the product of two 3-digit numbers.

Lets take the case: largest palindrome made from the product of two single-digit numbers.
what will be the smallest product of two single-digit numbers?
of-course the product of two smallest-single-digit numbers ie. 0 and 0 ie. 0-
and the largest product?
product of two largest-single-digit numbers ie. 9 and 9 ie. 81

Now we are interested in only palindrome numbers, that too between the above found numbers 
( 0 and 81 )List of palindrome numbers between 0 and 81: 1, 11, 22, 33, 44, 55, 66, 77
Note: 88 and 99 won't get into the list.
since we are looking for largest palindrome number which will be the product of two single-digit numbers,
let's go through the list from highest to lowest and with each number in the list, we will check if it is 
a product of two one digit number. 
We will stop traversing through the list of numbers when we find such a number.

Now let's do a little optimization to our logic. Why do we need to generate a list of all palindrome numbers 
below 81?
So first we will find the immediate palindrome number below 81, will check if it suffice our need, 
if not go for next.
Better.. , isn't it?

The same logic can be scaled up to find largest palindrome made from the product of two n-digit numbers.

We make use of a function in our code to divide the task.
"palindromeNumJustBelow ( input )":
returns the palindrome number just below the argument.
Rather than a brute-force search I use a few heuristics here:
	A palindrome number is a smaller number combined with the same number reversed.
	Eg:
		1221 = 12 combined with reverse of 12 ie 21
		765567 = 765 combined with reverse(765)
	In case of odd number of digits, it will be similar to above case but a digit in between.
	Eg:
		12821 = '12' + a digit(here '8') + reverse(12)
		12321 = '12' + '3' + '21'
	So a palindrome less than a number can be found by splitting the number into two sub-parts:
	In case of even number of digits:
		two numbers of half the number of digits ie 1221 into 12 and 21, 765567 into 765 and 567
	In case of odd number of digits:
		the small number and middle digit forms first number and reversed number forms the second 
		number ie 12821 into 128 and 21, 12321 into 123 and 21.
	Now the first number is decremented by 1. Eg: 12 of 1221 becomes 11, 765 of 765567 becomes 764
		128 of 12821 becomes 127, etc
	Now we just need to take the reverse of particular digits of this new number and append to the new 
        number to get the required palindrome number.
		ie. 	in case of even number of digits, just reverse the new number.
			in case of odd number of digits, reverse all digits except the last.

	Lets try our logic with a few numbers to ensure its correctness:
	1) Find the palindrome number just below 139890?
		This number has even number of digits ( 6 digits)
		It is split into two sub-parts: 139 and 890
		Now the first number is decremented by 1 and becomes 138.
		Now the reverse of new number is appended with the new number  to form the final answer.
			ie '138' + '831' = 138831 (Note: + doesn't mean mathematical addition)
		You may have a doubt now, why the first number is reduced and not the second number.
			If we reduce the second number and prepend with the reverse of new number, we wont get
			the expected result. In this case (831 - 1) = 830, '038' + '830' = 038830. Is this what
                        we wanted? 
			A BIG NO... !

	Now with a number of odd number of digits:
	2) 1637001
		yes, you are right, 7 digits
		right.., split into 1637 and 001
		Note: 001 wont be considered as 1
		1637 is decremented by 1 and becomes 1636
		Now, since odd number of digits, only 1, first 6 and 3 is reversed and appended.
		So final answer becomes: 1636361

	Lets go for one more
	3)	13300029212
		11 digits.
		133000 and 29212
		133000 - 1 = 132999
		'132999' + '99231' = 13299999231

"palindromeNumJustBelow ( long input )" implementation:
First, I insert each digit of the argument ie input into a vector. so the vector can be seen as an array 
of digits. This is for my easiness to handle the digits of the number. Since I use the push_back() function 
of the vector, The order of the digits will be reversed. Then I set a variable numOfDigits to number of digits 
in the number. Then a new number ie 'temp_input_half' is generated with last
half of digits (Note: last half digits means first half digits of the number, don't get confused).
'temp_input_half' is decremented by 1.
The second half digits in the vector are replaced with the digits of new value of 'temp_input_half'
Now our final array of digits is ready; we just need to form the final number out of it.
I have used two lambda functions in the code. It's just a way to define a function somewhere just for one time 
use. I use those with for_each loop.

At the top of the program, num_of_digits_in_num is defined as 3, ie. it should be a multiple of two 3-digit 
numbers.

In the main function:
I find 
	smallest 3-digit number 
		( to avoid hard-coding, we use 'num_of_digits_in_num', 
		so when i say 3 assume that I used 'num_of_digits_in_num' in the code) 
	largest 3-digit number
Then the execution gets into a while loop which exits if the "palindrome_num" (palindrome number) is less than 
the product of two smallest-3-digit-number. Product of two 3-digit-number should be between product of two 
smallest 3-digit number and product of two largest 3-digit number. It's simple mathematics.

Note: first the "palindrome_num" is set to product of two largest 3-digit number before the while-loop

Inside while-loop, we find a number just below the current "palindrome_num" and we use another for-loop which 
iterates from largest 3-digit number to smallest 3-digit number and in each iteration it is checked if it's 
possible to divide the palindrome number with the iteration variable (in our code, "temp_div1") and still get 
a 3-digit number

Largest palindrome made from the product of two 3-digit numbers is 906609 = 993 * 913


Code for reference:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <vector>
#include <boost/lambda/lambda.hpp>
#include <boost/functional.hpp>
#include <boost/function.hpp>

#define num_of_digits_in_num 3

using namespace std;
using namespace boost::lambda;

long palindromeNumJustBelow ( long input ) {
    vector inputAsArray; //array of single-digit-numbers

    long temp = input;
    while ( temp ) {
        inputAsArray.push_back ( temp%static_cast(10) );
        temp = floor( temp/static_cast(10) );
    }

    int numOfDigits = inputAsArray.size();

    temp = floor ( ( inputAsArray.size()/2 ) ) ;
    long temp_input_half = 0;
    boost::function f2 = ( var(temp_input_half)*=10, var(temp_input_half)+=boost::lambda::_1);
    for_each ( inputAsArray.rbegin(), inputAsArray.rend()-temp, f2 );

    temp_input_half--;

    long temp1 = temp;
    while ( temp_input_half ) {
        inputAsArray [ temp1++ ] = ( temp_input_half%static_cast(10) );
        temp_input_half = floor( temp_input_half/static_cast(10) );
    }

    // mirror all the digits from index temp till end
    while ( temp < numOfDigits ) {
        inputAsArray [ numOfDigits - temp -1 ] = inputAsArray [ temp ] ;
        temp ++ ;
    }

    temp = 0;
    boost::function f1 = ( var(temp)*=10, var(temp)+=boost::lambda::_1);

    for_each ( inputAsArray.rbegin(), inputAsArray.rend(), f1 );

    return temp;
}
int main ( int argc, char * argv[] ) {

    long num_min, num_max;
    if ( num_of_digits_in_num==1 ) {
        num_min = 0;
    }
    else {
        num_min = pow( static_cast(10), static_cast(num_of_digits_in_num-1) );
    }

    num_max = (pow( static_cast(10), static_cast(num_of_digits_in_num) ) - 1 );

    long prod_min, prod_max;
    prod_min = num_min*num_min;
    prod_max = num_max*num_max;

    long palindrome_num = prod_max;
    long temp_div2;

    bool ans_found = false;
    while ( palindrome_num > prod_min && !ans_found) {
        palindrome_num = palindromeNumJustBelow(palindrome_num);

        for (int temp_div1 = num_max; temp_div1 >= num_min && !ans_found; temp_div1-- ) {
            temp_div2 = palindrome_num/temp_div1;
            if ( palindrome_num % temp_div1 == 0 && temp_div2 <= num_max && temp_div2 >= num_min ) {
                cout << "Largest palindrome made from the product of two " 
                << num_of_digits_in_num << "-digit numbers is " << palindrome_num
                << " = " << temp_div1 << " * " << temp_div2 << endl;
                ans_found = true;
            }

        }
    }
}

Euler Problem: Solution of Problem-3 in C++

Q) The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 600851475143 ?

#include <algorithm>
#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

unsigned long largest_prime_factor_of ( unsigned long num ) {
    clog << "largest_prime_factor_of(" << num << ")" << endl;
    unsigned long largest_prime_divisor = -1;
    if ( num < 2 ) {
        return -1;
    }
    else if ( num >=2 && num<=3 ) {
        return num;
    }
    while ( num%static_cast<unsigned long>(2) == 0 ) {
        largest_prime_divisor = 2;
        cout << "/2" << endl;
        //cout << "num%static_cast(2) = " << num%static_cast(2) << " num/static_cast(2) = " << num/static_cast(2) << endl;
        num /= 2;
    }
    while ( num%3 == 0 ) {
        largest_prime_divisor = 3;
        cout << "/3" << endl;
        //cout << "num%static_cast(3) = " << num%static_cast(3) << " num/static_cast(3) = " << num/static_cast(3) << endl;
        num /= 3;
    }
    
    vector<unsigned long> prime_num_vector;
    prime_num_vector.push_back(static_cast<unsigned long>(3));
    
    clog << "largest_prime_divisor(after checking till 3) = " << largest_prime_divisor << "and num = " << num << endl; 

    unsigned long divisor = 3;
    bool divisor_is_prime;
    while ( (divisor+2) <= num ) {
        //cout << ".";
        divisor += 2;
        clog << "divisor = " << divisor << endl;
        divisor_is_prime=true;
        double sqrt_of_divisor = sqrt(divisor);
        clog << "sqrt_of_divisor = " << sqrt_of_divisor << endl;
        clog << "going inside for-loop" << endl;
        for( vector::iterator iter = prime_num_vector.begin(); 
             iter != prime_num_vector.end();
             iter++) 
        {
            clog << "\t*iter = " << *iter << endl;
            if ( *iter > sqrt_of_divisor ) {
                clog << "\t*iter > sqrt_of_divisor" << endl;
                break;
            }
            if ( divisor % *iter == 0 ) {
                clog << "\tdivisor_is_prime = false" << endl;
                divisor_is_prime = false;
                break;
            }
        }
        if ( divisor_is_prime ) {
            clog << "divisor_is_prime (" << divisor << ")" << endl;
            prime_num_vector.push_back ( divisor );
            
            while ( num % divisor == 0 ) {
                largest_prime_divisor = divisor;
                num /= divisor;
                cout << "largest_prime_divisor changed to " << largest_prime_divisor << " and num = " << num << endl;
            }
        }
    }
    clog << "returning " << largest_prime_divisor << endl;
    return largest_prime_divisor;
}

int main ( int argc, char *argv[] ) {
    unsigned long l = 600851475143 ;
    //unsigned long l = 12 ;
    cout << endl << "largest_prime_factor_of(l) = " << largest_prime_factor_of(l) << endl;
}

Euler Problem: Solution of Problem-2 in C++

Q) Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

 

Image

Reference:

#include <iostream>

#define MAX 4000000

using namespace std;
/*
Series: 1 1 2 3 5 8 13 21 34 55 89 144 ...
Series we are interested in: 2 8 34 144 ...
we can see a relation for the above series:
f(0) = 2
f(1) = 8
f(n) = 4*f(n-1) + f(n-2)
Now we dont need any check for even/odd
*/
int main ( int argc, char *argv[] ) {
    unsigned long var_a = 2 ;
    unsigned long var_b = 8 ;
    unsigned long sum = 0 ;
    unsigned long temp = 0 ;
    while ( var_b < MAX ) {
        sum += var_b ;
        //cout << endl;
        temp = var_b ;
        var_b = ( 4 * var_b + var_a ) ;
        var_a = temp ;
    }
    cout << sum << endl;
}

Big Data Series; Part 2: Program hadoop mapreduce in your favourite language.

Image

Apache hadoop gives you option to program your mapper and reducer in 
your favourite language.If you wonder about its possibility, you will
know it by yourself by going through this blog. Since python got into my favourite-language list recently,
let me try with it. Python already has a module: pydoop which
provides you with API to program map reduce. But this time,
we will program without using pydoop, thereby you will get
an idea how you can achieve the same in your preferred programming
language. Apache hadoop comes with a streaming jar which takes as
parameters: your mapper program, your reducer program, input file and
output file. It then streams the data, in your input file, to the
stdin (if I am going a bit too technical here, refer standard streams)
of mapper program. Your mapper program is supposed to read from stdin,
process the data and write to stdout as key-value pairs; its completely
upto you to choose the separator for key and value, since you are
going to get back those key-value data. The stdout of mapper is then
taken by the hadoop-streaming-jar, sorts the data from all mapper's
execution(fyi: mapper program is executed in all the data nodes, the
input file is chunked and stored), sorts that data based on key and
writes to the stdin of reducer program. Your reducer program should be
in such a way that it should read from stdin a key-value pair per line
and do the necessary processing to print out the final processed data.
Now, I will give you a feel of how things are going to work-out with a
character-count program, implemented in python, which will give your
the count of all alphabets in the input data.

Now let me show you my mapper and reducer code:
charcount_mapper.py:
Image


In charcount_mapper.py, I read line by line from stdin and go through
each line character by character and check if it's an alphabet. If it's
an alphabet, I print it to stdout in the format: "<character><tab-space>1". This
means to reducer program that the character appeared one time. Here
the key is <character> and value is '1'(one). There can be multiple
occurrence of same "<character><tab-space>1" depending on the input data.

charcount_reducer.py:
Image
Now lets analyze charcount_reducer.py. In this, I read line by line
from stdin, since its what I wrote into stdout from mapper program, I
can foretell that every line will be of the form:
"<character><tab-space>1". The only difference between what I wrote
into stdout from mapper program and what I get from stdin in reducer
program is that input will be sorted based on keys when I read in
reducer program. This will be helpful for me to construct logic for
reducer program. Now I just need to see if a new key is encountered.
Till then I keep on incrementing the counter. Once a new key is found,
the old key along with the counter value is printed out and counter is
reset. In the for loop, key along with counter value is printed out
only when a new key is encountered. Therefore I add one more print
statement at the end of the program to print out the last key and count.
(In case you are confused about the use of last print statement outside
the for-loop).
Since it will be hard to debug programs in hadoop I will ensure the
functionality of my program locally. I will use a sample input:
Image
You can easily predict the output our program should give out. Lets
see if we can get the same from the program.
Keep eyes on the command used in each screen-shot.
I will use the 'cat' command to print out the contents of the input file.
Image
It is then piped to mapper program.
Image
As I said this will the output of mapper program and to feed into
reducer program, for now, we will have to explicitly sort it.
Image
Now its ready to be fed to the reducer program:
Image
The output is as expected, isn't it!
Now lets run the same program in hadoop setup to see its success.
For that, start the hadoop running the start-all.sh script. (Refer the
part 1 of Big Data series in case of any confusion)
Then we need to copy our sample input file into HDFS file system. Know
the command to do it? Let me help you..
Before that I will create a directory for our use:
Image
Now we have a directory "charcount" in the path /user/thinker/ in the
Hadoop file-system. Lets copy our input file from my local file-system
to hadoop file-system.
Image
Lets ensure that the file's existence and its content:
Image
Image
Now we are sure about our input. Lets further with the execution.
For that, the command is:
Image

To ensure the availability of the hadoop-streaming jar, run the command:
Image
This is the jar which does the job of read the contents of input file
and feeding it to mapper program and ... (rest you already know)
the "-file" says the files which has your programs. The programs need
not be copies to HDFS. I used two "-file" to mention my mapper and
reducer files. "-mapper" mentions the mapper program's file name(only
file-name and not entire path). "-reducer" mentions the reducer program's
file-name. "-input" is used to mention the hdfs-absolute-path of input
file and "-output" mentions the output directory to which the output will
be written to.
Lets see the output of successful execution of the above command:
Image
Listing the contents of /user/thinker/charcount/:
Image
We can see a new directory with the name: sample_output.
Note: The command will fail to execute if you give an already existing
file/folder name with '-output' option.
Lets list the sample_output:
Image
Our output will be in 'part-*' files. Since the output size is very
small in this particular case, we have only one file. The number of
files increases with increase in output size.
Lets print the generated output for final verification.
Image
Even though the output differs in order, the counts are correct. You
can run the program with some other input by changing the file given
with '-input' option. You can use any language to
program your mapper and reducer. Points to be noted are:
Scripting languages with its jvm/interpreter installed in all the datanodes is a must.
In case of compiled languages like C or C++, you will have to compile it first and
the executable file need to be mentioned with '-file', '-mapper' and '-reducer'.
With that, I think I covered almost everything needed for you to kickstart your mapreduce
programming in your preferred language. See you in next part..

Big Data is a Big Deal.. :)

Big Data Series; Part 1: Set up Hadoop in ubuntu

Image

The reference given at the bottom most of this page can give you a detailed description on setup of Hadoop. I will take you through my experience in setting it up in Ubuntu.

You should have a linux/unix system with jvm installed and password-less ssh enabled.

Download the latest release of hadoop FROM

I prefer *.tar.gz to other installable packages because once you setup hadoop with installable packages, it will be hard for you to find the configuration files for any editing(from my experience; I removed it and installed with *.tar.gz).

Assuming that your browser downloaded the hadoop tar file to Downloads folder.

(in my case Image)

I chose /app folder to setup hadoop. So move the tar file to /app

Image

Unzip and un-tar the file there:

Image

You will need to edit the hadoop-env.sh file to set the JAVA_HOME environment variable.

If you try to start hadoop without this modification, hadoop will fail to start throwing the below error:

Image

gedit is a text editor I am using. You can prefer your favourite(vi/vim/textedit/…)

location of hadoop-env.sh (hadoop<version>/conf)

Image

You will find below lines in hadoop-env.sh

Image

Either edit the already existing line of add a new line as I did:

Image

You can know about your specific location with following commands:

Image

As you can see, I highlighted /usr/lib/jvm/java-7-oracle/jre/bin/java. hadoop expects us to specify the path till java-7-oracle ie. “/usr/lib/jvm/java-7-oracle”

This will be enough to kick-start your hadoop in stand-alone mode.

Since I plan to install Apache Pig for scripting, I will setup hadoop in pseudo Distributed mode. For that I need to edit three files: core-site.xml, hdfs-site.xml and mapred-site.xml which can be found in “hadoop<version>/conf/” directory. The same information can be found in the reference as well.

ImageImageImage

 

 

Now the recipe is ready. Before I can start hadoop there is this one final thing to be done: formatting of name-node. Assuming that you are in the hadoop main directory, run the command: “bin/hadoop namenode -format”

And you will see logs like below:Image

 

Done with the waiting part. Run the command “bin/start-all.sh” to run NameNode, Secondary NameNode, Data Node, Task Tracker and Job Tracker as back-end processes.

Image

To ensure that all five services are running, use jps command. If you see the below output, “ALL IS WELL..”

 

Image

Out of my experience in setting it up in different linux and unix variants including Mac, I can say, the same steps can be repeated in any *nix variants.

Big Data is a Big Deal.. 🙂

Reference:

http://hadoop.apache.org/docs/r1.1.1/single_node_setup.html

Obfuscated Code Unfolded..

What is the first thing that comes to your mind seeing this?

Screenshot of Obfuscated code
Screenshot of Obfuscated code

Seeing the first few lines may remember you of some programming language but what is rest? It made no sense to me too at first and then, slowly, it started unfolding in front of me.

Yes, this program has a pre-processor macro and if one exists in the program, it gets replaced, where-ever it is found in the rest of the program, by its value. Thereby, all the underscores(_) will be replaced by “-F<00||–F-OO–".
Thus during compilation, just after the pre-processor macro is made effective, the program will look like below:

Screenshot of code after preprocessing
Screenshot of code after preprocessing

Now lets unfold the mystery of this simple statement: -F 0(false)
0(false) || 1(true) ==> 1(true)
1(true) || 0(false) ==> 1(true)
1(true) || 1(true) ==> 1(true)

The beauty of || operator is its usability for selective execution of two statements. Consider a complex statement a||b where a and b are expressions or simple statements, b will be executed only if a returns false or 0;

Analyze the code: -F<00||–F-OO–;–F<00||–F-OO–;–F<00||–F-OO–;–F<00||–F-OO–;

At first F is 0, so –F or –0 or 0 is not less than 0, –F-OO- – is executed and – -F is a prefix decrement ie. F's value is decremented by 1 and stored in F before the entire statement is executed, O- – is a postfix decrement operation, ya you guessed it right, decrement will happen after the execution of this statement. Now after semi-colon the statement has a small change, instead of "-F<00||–F-OO–;" it is now "–F<00||–F-OO–;", an extra –ve symbol at front. Remember the value of F and OO is –1 now. Take the statement – -F< 0 ie. -(-(-1))<0 equivalent to –14.0*-(-16)/(-16)/(-16)
=>4.0*16/-16/-16
=>4.0*-1/-16
=>4.0*0.0625
=>0.25

Code for reference:
#define _ -F<00||–F-OO–;
int F=00,OO=00;
main(){
F_OO();
printf("%1.3f\n",4.*-F/OO/OO);
}

F_OO()
{
_-_-_-_
_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_
_-_-_-_
}

Ball in the Box (A C++&OpenGL game)

Ball in the Box is a simple game developed in C++ using OpenGL library during my free time, out of my interest to learn OpenGL. The latest version of it is 4.0. Since it is not in my present system, I will give you the 3.0 version’s source code. You are free to modify or copy or what-ever you like to do with this… 🙂

Before going into the code, let me give you a feel of my game:

Image

Image

Image

/*

File name : DisplayText.h

Author : Sreejith Sreekantan

Version : 3.0

Date : June 2012

*/

#ifndef __DisplayText_h__

#define __DisplayText_h__

#ifdef __APPLE__

#include <GLUT/glut.h>

#include <OpenGL/OpenGL.h>

#include <OpenGL/gl.h>

#else

#include <GL/glut.h>

#endif

#include

using namespace std;

namespace DisplayText {

void DisplayText(float posx, float posy, void* font, char string[]) {

glRasterPos2f(posx, posy);

while(*string) {

glutBitmapCharacter(font, *string);

string++;

}

}

void DisplayText(float posx, float posy, void* font, int value) {

int iTemp1=0, iTemp2 = value;

while(iTemp2>0) {

iTemp1++;

iTemp2 /= 10;

}

char *string = (char*)malloc(sizeof(char)*iTemp1+1);

sprintf(string, “%d”, value);

//clog << “string=” << *string << endl;

DisplayText(posx, posy, font, string);

}

}

#endif // __DisplayText_h__

/*

File name : BitB (Ball in the Box)

Author : Sreejith Sreekantan (krssreejith@gmail.com)

Version : 3.0

Date : June 2012

*/

#ifdef __APPLE__

#include <GLUT/glut.h>

#include <OpenGL/OpenGL.h>

#include <OpenGL/gl.h>

#else

#include <GL/glut.h>

#endif

#include “DisplayText.h”

#include

#include

#include

#include

using namespace std;

#define NAME_OF_GAME “Ball in the Box!”

// Game states

#define GAME_INIT 0

#define GAME_START 1

#define GAME_END 2

#define GAME_CLOSE 3

#define SCORE_OFFSET 5

#define SCREEN_WIDTH_PIX 120

#define SCREEN_HEIGHT_PIX 80

#define DASHBOARD_WIDTH_PIX SCREEN_WIDTH_PIX

#define DASHBOARD_HEIGHT_PIX 10

#define BALL_RADIUS 1.5

#define BALLSPEED_OFFSET 0.05

#define BOARD_WIDTH 5.0

#define BOARD_LENGTH 20.0

#define BOARD_HEIGHT 3

#define PLAYER_NAME_LEN 11

int iGameStatus;

int iScore;

int iScoreTemp=0;

GLfloat fBallSpeed = 0.01;

GLfloat fBoardSpeed = 4.0;

GLfloat afBallSpecular[] = {0.5, 0.0, 0.0, 1.0};

GLfloat afBallAmbient[] = {0.5, 0.0, 0.0, 1.0};

GLfloat afBallShininess[] = {50.0};

GLfloat fBallTransX = SCREEN_WIDTH_PIX/2;

GLfloat fBallTransY = SCREEN_HEIGHT_PIX/2;

GLfloat fBallTransXOffset = fBallSpeed;

GLfloat fBallTransYOffset = fBallSpeed;

GLfloat fBoardTransX = 0.0;

GLfloat fBoardTransY = 0.0;

GLfloat fBoardTransXOffset = fBoardSpeed;

char acPlayerName[PLAYER_NAME_LEN];

GLuint iSphereGenList;

GLuint iBoardGenList;

GLuint iDashboardGenList;

GLuint iGetNameGenList;

GLuint iShowScore;

time_t startTime;

void fnDisplay() {

glLoadIdentity();

gluLookAt(0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if (iGameStatus == GAME_INIT){

glPushMatrix();

glCallList(iGetNameGenList);

glColor3f(0.75, 0.0, 0.0);

DisplayText::DisplayText(SCREEN_WIDTH_PIX/2-8, SCREEN_HEIGHT_PIX/2, GLUT_BITMAP_HELVETICA_18, acPlayerName);

glPopMatrix();

}

else if (iGameStatus == GAME_START) {

iScore = ((time(NULL) – startTime)/SCORE_OFFSET);

if(iScore > 0 && iScore % (SCORE_OFFSET*2) == 0 && iScore != iScoreTemp) {

fBallTransX *= 1.025;

fBallTransY *= 1.025;

fBoardTransX *= 1.025;

fBoardTransY *= 1.025;

iScoreTemp = iScore;

clog << “Speed incremented:” << fBallTransX << “,” << fBallTransY << endl;

}

//clog << “iScore=” << iScore << endl;

glPushMatrix();

glTranslatef(fBallTransX, fBallTransY, 0.0);

glCallList(iSphereGenList);

glPopMatrix();

glPushMatrix();

glTranslatef(fBoardTransX, fBoardTransY, 0.0);

glCallList(iBoardGenList);

glPopMatrix();

glPushMatrix();

glCallList(iDashboardGenList);

glColor3f(1.0, 1.0, 1.0);

DisplayText::DisplayText(10.0, SCREEN_HEIGHT_PIX+5, GLUT_BITMAP_HELVETICA_18, acPlayerName);

DisplayText::DisplayText(SCREEN_WIDTH_PIX-10, SCREEN_HEIGHT_PIX+5, GLUT_BITMAP_HELVETICA_12, iScore);

glPopMatrix();

}

else if (iGameStatus == GAME_END){

glPushMatrix();

glCallList(iShowScore);

glColor3f(0.75, 0.0, 0.0);

DisplayText::DisplayText(SCREEN_WIDTH_PIX/2-8, SCREEN_HEIGHT_PIX/2, GLUT_BITMAP_HELVETICA_18, iScore);

glPopMatrix();

}

else if (iGameStatus == GAME_CLOSE){

exit(0);

}

glFlush();

}

void fnReshape(int w, int h) {

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(0, SCREEN_WIDTH_PIX, 0, SCREEN_HEIGHT_PIX+DASHBOARD_HEIGHT_PIX, 0.5, 2);

glMatrixMode(GL_MODELVIEW);

}

void fnIdle() {

//clog << “fnIdle():” << endl;

bool flag_x_offset_changed = false;

bool flag_y_offset_changed = false;

if (fBallTransX == SCREEN_WIDTH_PIX || fBallTransX == 0) {

fBallTransXOffset *= -1; // inverse x direction

flag_x_offset_changed = true;

}

if (fBallTransY == SCREEN_HEIGHT_PIX) {

fBallTransYOffset *= -1; // inverse y direction

flag_y_offset_changed = true;

}

if ((fBallTransX+BALL_RADIUS) >= fBoardTransX &&

(fBallTransX-BALL_RADIUS) <= (fBoardTransX + BOARD_LENGTH) &&

(fBallTransY-BALL_RADIUS) <= BOARD_HEIGHT &&

(fBallTransY) >= BOARD_HEIGHT) // if ball is hit by the board

{

fBallTransYOffset *= -1; // inverse y direction

iScore += SCORE_OFFSET;

flag_y_offset_changed = true;

}

if (fBallTransY == 0) {

glutIdleFunc(NULL);

iGameStatus = GAME_END;

clog << “Game status changed to GAME_END” << endl;

}

fBallTransX += fBallTransXOffset;

fBallTransY += fBallTransYOffset;

if (!flag_x_offset_changed) {

if (fBallTransX > SCREEN_WIDTH_PIX) {

fBallTransX = SCREEN_WIDTH_PIX;

}

else if (fBallTransX < 0) {

fBallTransX = 0.0;

}

}

if (!flag_y_offset_changed) {

if (fBallTransY > SCREEN_HEIGHT_PIX) {

fBallTransY = SCREEN_HEIGHT_PIX;

}

else if (fBallTransY < 0) {

fBallTransY = 0.0;

}

}

glutPostRedisplay();

}

void fnSpecial(int key, int x, int y) {

//clog << “fnSpecial():” << “key=” << key << ” x=” << x << ” y=” << y << endl;

switch (key) {

case 100: // left arrow key

if (fBoardTransX > 0.0 && iGameStatus == GAME_START) {

fBoardTransX -= fBoardTransXOffset;

}

break;

case 102: // right arrow key

if ( (fBoardTransX + BOARD_LENGTH) < SCREEN_WIDTH_PIX && iGameStatus == GAME_START) {

fBoardTransX += fBoardTransXOffset;

}

break;

//case 101: // up arrow key

//case 103: // down arrow key

default:

break;

}

glutPostRedisplay();

}

int iTemp =0;

void fnKeyboard(unsigned char key, int x, int y) {

clog << “fnKeyboard():” << “key=” << key << “(int)key=” << (int)key << ” x=” << x << ” y=” << y << endl;

switch (key) {

case 13: // if enter key pressed

if ( acPlayerName[0] != ” && iGameStatus == GAME_INIT) {

fBallTransX = SCREEN_WIDTH_PIX/2;

fBallTransY = SCREEN_HEIGHT_PIX/2;

fBallTransXOffset = fBallSpeed;

fBallTransYOffset = fBallSpeed;

glutIdleFunc(fnIdle);

iScore = 0;

startTime = time(NULL);

clog << “startTime=” << startTime << endl;

iGameStatus = GAME_START;

clog << “Game status changed to GAME_START” << endl;

}

else if (iGameStatus == GAME_END) {

iGameStatus = GAME_CLOSE;

clog << “Game status changed to GAME_CLOSE” << endl;

}

break;

case 8: // if backspace key pressed

if (iTemp >= 0 && iGameStatus == GAME_INIT) {

acPlayerName[–iTemp] = ”;

}

break;

case 27: // if escape key is pressed

if (iGameStatus == GAME_END) {

iGameStatus = GAME_INIT;

fnKeyboard(13, x, y);

return;

}

default:

if ( (key >= ‘a’ || key >= ‘A’) &&

(key <= ‘z’ || key <= ‘Z’) &&

iTemp < PLAYER_NAME_LEN-1 &&

iGameStatus == GAME_INIT

)

{

acPlayerName[iTemp++] = key;

acPlayerName[iTemp] = ”;

clog << “iTemp=” << iTemp << endl;

}

break;

}

glutPostRedisplay();

}

void init() {

//clog << “init():” << endl;

iGameStatus = GAME_INIT;

GLfloat light0_position[] = {-1.0, -1.0, -1.0, 0.0};

glLightfv(GL_LIGHT0, GL_POSITION, light0_position);

iBoardGenList = glGenLists(1);

glNewList(iBoardGenList, GL_COMPILE);

glEnable (GL_LINE_STIPPLE);

glLineStipple (1, 0x0F0F);

glColor3f(0.5, 0.75, 0.75);

glBegin(GL_LINES);

glVertex2d(0.0, BOARD_HEIGHT);

glVertex2d(BOARD_LENGTH, BOARD_HEIGHT);

glEnd();

glDisable(GL_LINE_STIPPLE);

glEndList();

iSphereGenList = glGenLists(1);

glNewList(iSphereGenList, GL_COMPILE);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);

glMaterialfv(GL_FRONT, GL_SPECULAR, afBallSpecular);

glMaterialfv(GL_FRONT, GL_AMBIENT, afBallAmbient);

glMaterialfv(GL_FRONT, GL_SHININESS, afBallShininess);

glutSolidSphere(BALL_RADIUS, 10, 10);

glDisable(GL_LIGHT0);

glDisable(GL_LIGHTING);

glEndList();

iDashboardGenList = glGenLists(1);

glNewList(iDashboardGenList, GL_COMPILE);

glColor3f(0.0, 0.5, 0.5);

glBegin(GL_POLYGON);

glVertex2d(0, SCREEN_HEIGHT_PIX);

glVertex2d(0, SCREEN_HEIGHT_PIX+DASHBOARD_HEIGHT_PIX);

glVertex2d(SCREEN_WIDTH_PIX, SCREEN_HEIGHT_PIX+DASHBOARD_HEIGHT_PIX);

glVertex2d(SCREEN_WIDTH_PIX, SCREEN_HEIGHT_PIX);

glEnd();

glColor3f(1.0, 1.0, 1.0);

DisplayText::DisplayText(1.0, SCREEN_HEIGHT_PIX+5, GLUT_BITMAP_HELVETICA_12, “Player:”);

DisplayText::DisplayText(SCREEN_WIDTH_PIX-20, SCREEN_HEIGHT_PIX+5, GLUT_BITMAP_HELVETICA_12, “Score:”);

glEndList();

iGetNameGenList = glGenLists(1);

glNewList(iGetNameGenList, GL_COMPILE);

glColor3f(0.0, 0.5, 0.5);

glBegin(GL_POLYGON);

glVertex2d(20, SCREEN_HEIGHT_PIX/2-20);

glVertex2d(20, SCREEN_HEIGHT_PIX/2+20);

glVertex2d(SCREEN_WIDTH_PIX-20, SCREEN_HEIGHT_PIX/2+20);

glVertex2d(SCREEN_WIDTH_PIX-20, SCREEN_HEIGHT_PIX/2-20);

glEnd();

glColor3f(0.8, 0.8, 0.8);

DisplayText::DisplayText(23.0, SCREEN_HEIGHT_PIX/2+10, GLUT_BITMAP_HELVETICA_18,

“Enter your name and press enter to continue.”);

glBegin(GL_POLYGON);

glVertex2d(SCREEN_WIDTH_PIX/2-20, SCREEN_HEIGHT_PIX/2-7);

glVertex2d(SCREEN_WIDTH_PIX/2-20, SCREEN_HEIGHT_PIX/2+7);

glVertex2d(SCREEN_WIDTH_PIX/2+20, SCREEN_HEIGHT_PIX/2+7);

glVertex2d(SCREEN_WIDTH_PIX/2+20, SCREEN_HEIGHT_PIX/2-7);

glEnd();

glEndList();

iShowScore= glGenLists(1);

glNewList(iShowScore, GL_COMPILE);

glColor3f(0.0, 0.5, 0.5);

glBegin(GL_POLYGON);

glVertex2d(20, SCREEN_HEIGHT_PIX/2-20);

glVertex2d(20, SCREEN_HEIGHT_PIX/2+20);

glVertex2d(SCREEN_WIDTH_PIX-20, SCREEN_HEIGHT_PIX/2+20);

glVertex2d(SCREEN_WIDTH_PIX-20, SCREEN_HEIGHT_PIX/2-20);

glEnd();

glColor3f(0.8, 0.8, 0.8);

DisplayText::DisplayText(30.0, SCREEN_HEIGHT_PIX/2+10, GLUT_BITMAP_HELVETICA_18,

“Your present score is”);

DisplayText::DisplayText(23.0, SCREEN_HEIGHT_PIX/2-17, GLUT_BITMAP_HELVETICA_18,

“Press enter to exit or escape to continue..”);

glBegin(GL_POLYGON);

glVertex2d(SCREEN_WIDTH_PIX/2-20, SCREEN_HEIGHT_PIX/2-7);

glVertex2d(SCREEN_WIDTH_PIX/2-20, SCREEN_HEIGHT_PIX/2+7);

glVertex2d(SCREEN_WIDTH_PIX/2+20, SCREEN_HEIGHT_PIX/2+7);

glVertex2d(SCREEN_WIDTH_PIX/2+20, SCREEN_HEIGHT_PIX/2-7);

glEnd();

glEndList();

glLineWidth(BOARD_WIDTH);

glClearColor(0.5, 0.5, 0.5, 1.0);

glEnable(GL_BLEND);

glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

}

int main(int argc, char **argv) {

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE);

glutInitWindowSize(600, 400);

glutInitWindowPosition(100, 100);

glutCreateWindow(NAME_OF_GAME);

init();

glutDisplayFunc(fnDisplay);

glutReshapeFunc(fnReshape);

//glutIdleFunc(fnIdle);

glutSpecialFunc(fnSpecial);

glutKeyboardFunc(fnKeyboard);

glutMainLoop();

}

Not a big deal.. I know.. but a beginner in OpenGL will find it useful.. 🙂

‘const’ keyword and pointers in C++ (CPP) language

Many a times one of the challenges a beginner faces is with the use of const keyword. It comes handy when one understands the exact use of it. Const keyword changes its meaning depending on where it is being used. Below I give all possible use of the keyword.

Normal integer variable:
           int intValue                                                                            // integer variable
           As function parameter:
                       Void testFunc(int intValue) {
                                   // modification of intValue is possible
                                   intValue = 10;
                       }
                       Here the value passed to testFunc() is copied to a separate memory area, which can be accessed through intValue

Pointer to integer variable:
           int *ptrToInt                                                              // pointer to integer variable
           As function parameter:
                       void testFunc(int *ptrToInt) {
                                   int a = 10;
                                   cout << ptrToInt << endl;               //prints the memory address of passed variable
                                   cout << *ptrToInt << endl;

                                   ptrToInt = &a;                                               //assigning address of variable ‘a’ to ptrToInt ie. Modification of ptrToInt is possible

                                   cout << ptrToInt << endl;               //prints the memory address of variable a
                                   cout << *ptrToInt << endl;  //prints the value of a ie. 10
                       }

Constant integer value:
           int const constInt                                                      // constant variable, cant be modified
          const int constInt                                                      // also
           As function parameter:
                       void testFunc(int const constInt) {
                                   //constInt can’t be changed here
                       }

Pointer to constant integer:
           int const *ptrToConstInt                                          // pointer to a constant integer variable
          const int *ptrToConstInt                                          // also
           As function parameter:
                       void testFunc(const int *ptrToConstInt) {
                               const int a = 10;
                                   ptrToConstInt = &a;
                                   cout << ptrToConstInt << endl;               // prints the memory address of variable a
                               cout << *ptrToConstInt << endl;            // prints the value of a ie. 10
                       }

Constant pointer to an integer:
           int *const constPtrToInt                                           // constant pointer to integer variable
           As function parameter:
                       void testFunc(int *const constPtrToInt) {
                                   //constPtrToInt cant be changed but the value it points to, can be altered
                                   *constPtrToInt += 10;                 //since it points to, is a normal integer value
                       }

Constant pointer to constant integer:
           int const * const constPtrToConstInt          // constant pointer to constant integer value
           As function parameter:
                       void testFunc(int const *const constPtrToConstInt) {
                                   //here the value of constPtrToConstInt as well as the value it points to, both is immutable
                       }

MORE USE OF ‘const’ KEYWORD:

Constant pointer to a constant pointer to an integer:
           int * const * const const_ptr_to_const_ptr_to_int

Constant pointer to a pointer to a pointer:
           int ** const const_ptr_to_ptr_to_int

Pointer to a constant pointer to an integer:
           int * const * ptr_to_const_ptr_to_int

Pointer to a pointer to an integer:
           int ** ptr_to_ptr_to_int

Tip: “int const” and “const int” are same. So if the line contains any of these two, understand that the final part is “integer constant” take the rest of the line and read backwards,
                       *                     ==means==>         ‘pointer to’
                       * const            ==means==>         ‘constant pointer to’
                       Multiple ‘*’        ==means==>         that number of ‘pointer to’

 

Hope this post was helpful to you… 🙂

Essential Coding Standards in Java

Know more about coding standards and comments
• What is the need of coding standards and comments?
Coding standards and comments are for the programmer’s ease of understanding the program. They improve the readability of the software.
Another good reason for the need of coding standards and appropriate comments in the program is that, more than 75% of the lifetime cost of a piece of software goes to maintenance and any software is hardly maintained by its original author for its whole life. In this case, appropriate comments in the program will help the new engineers understand the logic of the original author of the program, quickly and thoroughly and take the project further. It will also be helpful to the author of the program in recollecting the logic he has used in it, in a later point of time.
• Do the comments in the program get compiled into the final executable file?
No, all the comments and blank spaces put into program as part of indentation are filtered out at the time of compiling.

Coding Standards
1. Packages
• Package names should help in understanding the program and functions of the files in it.
• Package name should have a proper hierarchy and should be in all-lowercase.
• Files of similar functionality should be put into same package.
• Use different sub packages if needed, instead of putting all your source files into one package.
• Prefix of a package name should always be one of the top-level domain names: com, edu, gov, mil, org or English two-letter codes of countries according to ISO Standard 3166, 1981 and rest of the package name can be according to the internal naming convention of the organization, it can specify division, department, working-unit, etc.
• Eg:
com.infosys.tvm.ped.apple
2. Files
• Files can have maximum of 2000 lines of code.
• Separate different sections of your file with a blank line.
• Write an optional comment for each section for identifying it.
2.1. Source files
• Source files can contain a single public class or interface.
• Private classes and interfaces associated with public classes can be put in the same source file as the public class.
• Public class or interface should be in the beginning of the source file.
• Source file structure:
o Source file should start with a comment of format given below:
/*
*Class name:
*
*Version information:
*
*Date:
*
*Copyright notice:
*/
 Eg:
/*
*
*HelloWorld.java 1.09 11th Oct 1989
*
*/
o Package and import statements:
package com.infosys.ped.apple;
import java.util.*;
o Class and Interface declarations.
2.1.1. Classes
• Class names should be nouns, in mixed case with the first letter of every word capitalized.
Eg:
class Infosys;
class InfosysEmployee
• Class names should be simple and descriptive.
• Use only widely used abbreviations and acronyms in class names; rest of the words should be as whole-words.
• Comment for the class:
/*
*Class description:
*
*Version:
*
*Author:
*/
2.1.2. Interfaces
• Interface name should follow all the standards as class names.
• Eg:
interface Car;
interface InfosysClient;
2.1.3. Methods
• Method names should be verbs in mixed cases, with starting letter lowercase and first letter of all internal words capitalized.
Eg:
erase();
getName();
averageWorkHours();

• Methods should be prefixed with a comment, describing the purpose of it, its argument list and its return value.
• Separate methods with a blank line.
• There should not be space between method name and parenthesis and opening curly braces need to be in the same line as method header; use a new line for closing curly brace.
Eg:
void sayHelloToWorld() {
String stringToPrint = “Hello World… “;
. . .
if (conditional_expression) {
System.out.println();
. . .
}
. . .
}

2.1.4. Variables
• Variable names should be in mixed case with starting letter lowercase and first letter of all internal words capitalized.
• Variable names should be short and meaningful. It should indicate the intent of its use.
• Variable names should not start with underscore (“_”) or dollar sign (“$”) even though it’s possible.
• Do not wait to declare variables until their first use.
• Variables of one character length should be avoided except for temporary variables. Common practice is to use i, j, k, m and n for integers and c, d and e for characters.
Eg:
int i;
char c;
float mySalary;
• Prefer tabs to space between data type and variables. This will make your program look aligned.
Eg:
String unitName; //preferred
int noOfEmployees; //preferred

String unitName; //not a good practice
int noOfEmployees; //not a good practice
• Using a new line for every declaration and commenting it is a good practice.
Eg:
int myAge; //present age of the user
float mySalary //annual income of the user
• Avoid declaration different types in same line.
Eg:
String name, nicknames[5]; //Wrong
2.1.5. Constants
• Constant variable’s name should be fully capitalized with words separated by underscore (“_”)
• Eg:
static final int MAX_AGE_LIMIT=65;
3. Indentation
• Avoid lines longer than 80 characters. Programs should be readable without scrolling horizontally.
• Break expressions, either after a comma or before an operator, which does not fit in a single line. Indent it properly to avoid confusion.
• Eg:
var = myFunction1( myParameter1, myParameter2, myParameter3,
myParameter4, myParameter5);
float sum1 = someNumber1 + someNumber2 + someNumber3
+ (someNumber4 – someNumber5);
Good programming practices
• Use library utilities wherever possible, instead of coding your own logic. Library utilities are optimized for speed and performance and use of these will make the program perform better.
• var1++; var2++; //Wrong practice

var1++; //Correct
var2++ //Correct
• Always use curly braces with “ if ” conditions and “ for ” statements even if there is only one statement inside the block.
• Separate expressions in a “ for ” statement with a blank space.
Eg:
for (expression1; expression2; expression3)
• Do not declare any of the class or instance variables as public unless its unavoidable.
• Avoid using of the instance variables to access class variables.
• zoo.var1 = boo.var2 = 2; //Wrong; makes the program complicated to read
• if (c==d && d==e) //Wrong practice
if ((c==d) && (d==e)) //Correct
• i == 1 ? 100 : 0; //Wrong practice
(i==1) ? 100 : 0; //Correct

References
http://www.oracle.com/technetwork/java/codeconvtoc-136057.html