Pages

Sunday, 31 October 2010

Know the Version of Ubuntu

To know the version of Ubuntu (GNU/Linux) you are running, just enter
cat /etc/issue
in the bash terminal.

Sunday, 24 October 2010

Generate Star Pattern

The below code is in AS 3.0.
First from the components drag the TextArea component to the stage. Then give it an instance name txt. Then begin hacking.
var lines:int = 5;
var star:String = "*";
var space:String = " ";

var i:int;
var j:int;
var k:int;
var str:String="";

function init():void
{
    /* Upper Triangle */
    for( i=0; i< lines; i++ ) {
        j = i;
        str = "";
        for( k=0; k<5-i; k++ ) {
            str += space;
        }
        while( j != 0 ) {   
            str += star + space;
            j--;
        }
        txt.text += str + "\n";
    }

    /* Lower Triangle */
    for( i=lines; i!=0; i-- ) {
        j = i;
        str = "";
        for( k=0; k<5-i; k++ ) {
            str += space;
        }
        while( j != 0 ) {   
            str += star + space;
            j--;
        }
        txt.text += str + "\n";
    }
}

init();
//Output
    * 
   * * 
  * * * 
 * * * * 
* * * * * 
 * * * * 
  * * * 
   * * 
    * 
The idea behind this
Its easier to think with lower triangle taken first. For the time being lets consider that we need only the lower triangle. i.e, say there will be 5 lines, and in the first line there will be 5 stars, in the second line there will be 4 stars and so on.
Think that if we simply put a for loop with the number of lines (5) and decrement it, in the first iteration we get 5, second iteration 4, (yeah, I know everyone knows that!), which is the number of stars we need to show per line. Now what we need is to actually display those number of stars.
The idea is concatenate those number of stars into a string and display them. Now what we get is a right angled triangle. That's because we need to concatenate the correct space along with the string. That's what the for loops in line number 16, and 30 does.
Now we have required triangle. You can easily make a recursive version if you would like.

Friday, 22 October 2010

Bitwise Shift Operator Performance

Bitwise shift operators ( shift left <<, and shift right >> ) can be used in multiplying and dividing if the divisor is a power of 2. Here I ran a test which shows that bitwise shift operators perform twice faster than the multiplication or division operators.

Shift Right ( >> )
When you need to divide a number by 2 or its power we can instead use shift operator. You read more about the theory behind it elsewhere, say wikipedia.
//shift right ( divide )
trace( 12 >> 1 );    //6
trace( 12 >> 2 );    //3
//shift left ( multiply )
trace( 12 << 1 );    //24
trace( 12 << 2 );    //48
Shifting right by one position is similar to divide by 2, and shifting right by two position is similar to divide by 4.
Similarly, is the case with shift left ( << ) where you will be multiplying the value instead.
// bit shift vs divide operator performance
var bigNum:int = 100000000;    //8-zeros
var i:int=0;

function computeDiv():void
{
    for( i=0; i<100000000; i++ ) {
        bigNum = bigNum / 2;
    }
}

function computeShift():void
{
    for( i=0; i<100000000; i++ ) {
        bigNum = bigNum >> 1;    //shift right
    }
}

var t0:Number = getTimer();
trace( t0 );    //22
computeDiv();
var t1:Number = getTimer();
trace( t1 );    //4017
trace( "Time elapsed (Division): " + String( t1 - t0 ) );    //3995

var t2:Number = getTimer();
trace( t2 );    //4017
computeShift();
var t3:Number = getTimer();
trace( t3 );    //5689
trace( "Time elapsed (Shift): " + String( t3 - t2 ) );    //1672
This shows that the bit wise operators perform better than multiplication or division operators. This is tested using the debug version of the flash player. Using the normal version might show better results.

Monday, 11 October 2010

ActionScript 3 Performance Analysis

I was reading the post written in a blog (post1, post2) where the author compares various languages (Erlang, Python, Ruby, C, JavaScript, Lua, PHP, Common Lisp, Haskell), using a program which computes Pythagorean triplets. I just tried with ActionScript 3 and I'm not able to post any comments in that blog. So I'm writing it here.
import flash.utils.Timer;

var t0:int = getTimer();
trace( "result: " + pythag( 5000 ) );
var t1:int = getTimer();
trace( "Elapsed Time (s): " + String( ( t1 - t0 ) / 1000 ) );

function pythag( n:int ):int 
{
    var a:Number;
    var b:int;
    var c:int;
    var i:int;

    for( c=2; c<=5000; c++ ) {
        for( b=1; b < c; b++ ) {
            a = Math.sqrt( c*c - b*b );
            if( Math.floor( a ) == a ) {
                i++;
            }
        }
    }
    return i;
}
Time elapsed is 3.53 s. That's fast. Giovanni Intini (the author of that post) was running on a dual core MacBook Pro. I'm running this on a Pentium D dual core. So it must be a fair comparison. So here are the comparison from that site:
C: 0.40s
Lua: 3.44s
ActionScript 3: 3.53s
Erlang(smp): 3.95s
Erlang (non-smp): 5.66s
PHP5: 8.9s
Python(2.5.1): 11.2s
Ruby: 12.30s
JavaScript: -- (script stopped -taking too much time).

Tuesday, 5 October 2010

Recursion Using Anonymous Function in ActionScript 3

You must be familiar with recursion with normal functions, i.e a function calling itself. An anonymous function is a function without a name. So to use recursion in an anonymous function you call the arguments.callee() to refer to the anonymous function.
If its a normal function we can call that function using its name. Anonymous function don't have name, but you can refer the function using the callee method.

How to approach recursion?
The key idea to recursion is the terminating condition. First you need to figure out when the function should terminate. Then you think on how to generalize. Means first you look at when the factorial function say fact(n) should terminate, i.e, when n==1.

A normal function that computes factorial (I'm choosing factorial because its simple, and easy to understand) can be like:
function fact(n):int {
    if(n==1) return 1;
    else return n * fact(n-1);
}
trace(fact(5));
In terms of anonymous function:
var fact:int = (function(n):int {
    if(n==1) return 1;
    else return n * arguments.callee(n-1);
})(5);

trace(fact);

Function Arguments in Depth

Function which takes infinite arguments
function infiniteArgs(...args):void {
    trace( args );
}
infiniteArgs( 1, 2 );
infiniteArgs( 1, 2, 3, 4, 5 );
infiniteArgs( 1, 2, 3, 4, 5, 6, 7 );
infiniteArgs( 'a', 'b', 'c' );
Another method without all this hassle is to do like the below. I recommend this instead of the above method:
var inf:Function = function():void {
    trace(arguments);
}
inf( 1, 2, 3, 4 );
inf( 'a', 'b' );
Arguments array
function foo( a:int, b:int, c:int ):void {
    trace( arguments );    //displays the arguments passed
}
foo( 1, 2, 3 );
foo( 0, 10, 110 );
It will display the arguments passed into the function.
Now you can use arguments.length, arguments[0] etc.
function foo( a:int, b:int, c:int ):void {
    trace( "args: " + arguments );
    trace( "len: " + arguments.length );
    trace( "arguments[2]: " + arguments[2] );
}
foo( 1, 2, 3 );
foo( 1, 10, 110 );
When using mutliple parameters the arguments are referred by the variable that you put after the 3 dots. i.e:
function foo(...myCoolArgs):void {
    //instead of myCoolArgs if you gave arguments you'll get undefined error.
    trace( "args: " + myCoolArgs );
    trace( "len: " + myCoolArgs.length );
}
Passing arguments to another function
You have a function which received arguments. You need to send those arguments to another function as arguments itself instead of an array. For that you can use the 'apply' function.
//normal situation
function fooA(...myCoolArgs):void {
    trace( "args: " + myCoolArgs );
    trace( "len: " + myCoolArgs.length );    //you get 5
    fooB( myCoolArgs );
}

function fooB(...args):void {
    trace( "args: " + args ); 
    trace( "len: " + args.length );    // you get 1 instead of 5
}

fooA( 0, 1, 2, 3, 4 );
Its passed as an argument array. So what you do is:
function fooA(...myCoolArgs):void {
    trace( "args: " + myCoolArgs );
    trace( "len: " + myCoolArgs.length );    //you get 5
    fooB.apply( this, myCoolArgs );    //pass it like this
}

function fooB(...args):void {
    trace( "args: " + args ); 
    trace( "len: " + args.length );    // now you get 5
}

fooA( 0, 1, 2, 3, 4 );
More cooler version:
var fooA:Function = function():void {
    trace( "args: " + arguments );
    trace( "len: " +  arguments.length );
    fooB.apply( this, arguments );
}

var fooB:Function = function():void {
    trace( "args: " + arguments ); 
    trace( "len: " + arguments.length );
}

fooA( 0, 1, 2, 3, 4 );
fooA( 'a', 'b', 'c' );

Self invoking functions in ActionScript 3

Consider this normal example:
function greetings():void 
{
    trace( "Hello World" );
}
greetings();
This will display "Hello World".

The above example can be written in more elegant way (i.e., self invoking the function) as:
(function greetings():void {
    trace( "Hello World" );
})();
You get the same result. It's a function expression. Function expression syntax is of the form:
( f )();
Another example:
(function greetUser( name:String ):void {
    trace( "Hello " + name );
})("Awesome");
You pass an argument during self invocation.

However one important thing you must consider is the scope.
(function greetUser( name:String ):void {
    trace( "Hello " + name );
})("Awesome");

greetUser( "Foo" );  //will result in error
So note that.

Sunday, 3 October 2010

Install Consolas font in Windows without Visual Studio

Consolas is a good programmer's font. You can download it freely from Microsoft. But to install it you need Visual Studio installed. But here I'll show you how to install it without having VS installed.
1. Download the original font setup from the Microsoft website.
2. Download and install Orca. Orca is a Windows Installer package editor.
3. Now run the consolas installer. You'll get an error message. But don't close the installer. Instead navigate to your %temp% directory and you'll see a (random_string).msi file. Copy it to another directory and exit the installer.
4. Right-Click the now obtained msi file and choose "Edit with Orca".
5. In Orca, in the left pane look for "LaunchCondition".
6. Toggle the value of "IS_VSS_INSTALLED". (Or you can just right-click the row and choose "Drop Row").
7. Save the changes, close Orca and run the patched installer.