Thursday, November 10, 2011

Learning MSBuild

In my last 7 years of my career, I mostly worked on Unix based builds. Now I got curious to explore Windows builds. I learnt the 2 prominent build assistants in Windows are MSBuild and Nant. In this blog, I will share my learning experience of MSBuild.


What is MSBuild?
MSBuild is the build platform for Microsoft and Visual Studio. Programming languages that target the .NET Framework, for example, Visual C# and Visual Basic, use MSBuild project files to describe and control the application build process. When you use Visual Studio to create an MSBuild project file, the appropriate XML is added to the file automatically. 


Lets start by creating a simple C# file and compiling it through csc compiler. csc is a C# compiler, it comes along with .NET Framework (version 2.0, 3.5, or 4.0).
1) cd D:\HelloWorld
2) Create a file Helloworld.cs , with it's content as
using System;
class HelloWorld
{
    static void Main()
    {
#if DebugConfig
        Console.WriteLine("WE ARE IN THE DEBUG CONFIGURATION");
#endif
Console.WriteLine("Hello, world!");
    }
}
3) Very likely csc compiler location  won't be in your path. Set it
    set PATH=%PATH%;%WINDIR%\Microsoft.Net\Framework64\v2.0.50727
    Alternatively, if you have Visual Studio installed, you can use the Visual Studio Command Prompt, which has a path that includes the MSBuild folder.
4)  Compile it
    csc Helloworld.cs
5) Test the application by typing Helloworld.exe at the command prompt
     O/p: Hello, world!
6) Delete the application
    del helloworld.exe 
Now let's do the same thing using MSBuild project file. We are creating a minimal MSBuild project file and it's content will be saved in a file named "Helloworld.csproj".

<!-- root Project node   -->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">


  <!--ItemGroup node contain item elements   -->
  <ItemGroup>
    <!-- An item element that refers to the application source file. -->
    <Compile Include="helloworld.cs" />
  </ItemGroup>


  <!-- A Target node to contain tasks that are required to build the application.  -->
  <Target Name="Build">
    <!-- A Task element to start the Visual C# compiler to build the application.  -->
    <Csc Sources="@(Compile)"/>
  </Target>
</Project>

Building the application using MSBuild project file
Command: msbuild Helloworld.csproj /t:Build 
This builds the Build target of the Helloworld project file by invoking the Visual C# compiler to create the Helloworld application.
Output:

Microsoft (R) Build Engine Version 2.0.50727.42
[Microsoft .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation 2005. All rights reserved.
Build started 2011-11-11 12:05:00 PM.
Project "D:\siddesh\learning-msbuild\HelloWorld\Helloworld.csproj" (Build target(s)):
Target Build:
    C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\Csc.exe /out:helloworld.exe helloworld.cs
Build succeeded.
    0 Warning(s)
    0 Error(s)
Time Elapsed 00:00:01.12

For detailed build, add flag
   msbuild Helloworld.csproj /t:Build /verbosity:detailed


Improving MSBuild project file - Properties

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- PropertyGroup element is used to define variables/properties -->
  <PropertyGroup>
    <AssemblyName>MSBuildSample</AssemblyName>
    <OutputPath>Bin\</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="helloworld.cs" />
  </ItemGroup>
  <Target Name="Build">
    <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
    <!-- The MakeDir task creates a folder that is named by the OutputPath property, provided that no folder by that name currently exists. -->
    <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
    <!--This instructs the Visual C# compiler to produce an assembly that is named by the AssemblyName property and to put it in the folder that is named by the OutputPath property. -->
  </Target>
</Project>

Improving MSBuild project file - Adding build targets


<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This sets the Build target as the default target. -->
  <PropertyGroup>
    <AssemblyName>MSBuildSample</AssemblyName>
    <OutputPath>Bin\</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="helloworld.cs" />
  </ItemGroup>
  <Target Name="Build">
    <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
    <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
  </Target>
  <!-- The Clean target invokes the Delete task to delete the application. -->
  <Target Name="Clean" >
    <Delete Files="$(OutputPath)$(AssemblyName).exe" />
  </Target>
  <!-- The Rebuild target does not run until both the Clean target and the Build target have run. -->
  <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
</Project>

Testing:
1) msbuild helloworld.csproj /p:AssemblyName=Greetings
    MSBuild runs the default Build target. The /p switch overrides the AssemblyNameproperty and gives it the new value, Greetings. This causes a new application, Greetings.exe, to be created in the \Bin\ folder.
2) msbuild helloworld.csproj /t:clean
  This runs the Clean task to remove the application that has the default AssemblyName property value, MSBuildSample.
3) msbuild helloworld.csproj /t:clean /p:AssemblyName=Greetings.
This runs the Clean task to remove the application that has the given AssemblyName property value, Greetings.
4) msbuild
Although a project file is not specified, MSBuild builds the helloworld.csproj file because there is only one project file in the current folder. 
Reference: http://msdn.microsoft.com/en-us/library/dd576348.aspx

Wednesday, November 9, 2011

Solution to Project Euler Problem 9 - Finding Pythagorean triplets

http://projecteuler.net/problem=9

Problem: 

A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a2 + b2 = c2
For example, 32 + 42 = 9 + 16 = 25 = 52.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.

Answer:
    (200*200) + (375*375)) == (425 * 425)
      40000 + 140625 = 180625
        200 + 375 + 425 = 1000

Solution:
#!/usr/bin/perl -w
use strict;

my ($a,$b,$c,$ulimit);
$ulimit=1000;

print "Pythogon triplets \n";
for ($a=1;$a<=$ulimit;$a++)   {
  for ($b=1;$b<=$ulimit;$b++ ) {
    if ($a < $b ) {
      for ($c=1; $c<=$ulimit;$c++) {
        if ( $b < $c ) {
          if ( (($a*$a) + ($b*$b)) == ($c * $c) ) {
            print "  ($a*$a) + ($b*$b)) == ($c * $c) \n";
            my $aa=$a*$a;
            my $bb=$b*$b;
            my $cc=$c*$c;
            print "    $aa + $bb = $cc \n";
            if ( ($a + $b + $c) == 1000 ) {
                print "FOUND: $a + $b + $c = 1000 \n";
                exit(0);
            }
          }
        }
       }
    }
  }
}


Saturday, November 5, 2011

Solution to Project Euler Problem 8 - greatest product of five consecutive digits in a 1000-digit number.

http://projecteuler.net/problem=8

Problem:


Find the greatest product of five consecutive digits in the 1000-digit number.
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188

84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450

Answer: The greatest product of five consecutive digits is: 40824
            i.e 9*9*8*7*9=40824

Solution: 
# Store this 1000 digit number in a file named p8-input.txt

#!/usr/bin/perl -w
use strict;
my (@number, @temp, $end, $i,$j,@sum);


open (FH, "p8-input.txt") || die "Cant open p8-input.txt $! ";


#Read input file into array, by splitting each number
foreach() {
        chomp($_);
        #Split a number into array
        @temp = ( $_ =~ m/./g ) ;
        @number=(@number, @temp );
}
#for thousand numbers, for loop should end at index 996 (index starts from 0)
$end=$#number-3;


for ($i=0;$i<$end;$i++) {
#Keep finding sum of consecutive 5 numbers and store it in an array
        $sum[$i]=$number[$i]*$number[$i+1]*$number[$i+2]*$number[$i+3]*$number[$i+4];
        print "$number[$i]*$number[$i+1]*$number[$i+2]*$number[$i+3]*$number[$i+4]=$sum[$i] \n";
}


#sort the sum array numerically
@sum=sort{ $a <=> $b } @sum;


print "The greatest product of five consecutive digits is: $sum[$#sum] \n";




Solution to Project Euler Problem 7 - 10001th prime number

http://projecteuler.net/problem=7
Problem:

By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?

Answer: The 10001 prime number is: 104743

Solution:
#!/usr/bin/perl -w
use strict;
use Math::Complex;
my (@primes,$ulimit,$stop);
$ulimit=1000000;
$stop=10001;
generate_prime();


sub generate_prime {
        my ($i,$j,$prime,$squareroot,$count);
        @primes=(2,3,5,7);
        $count=4;
        #We know only 2 is the even prime numbers, hence skip all even numbers
        for ($i=9;$i<=$ulimit; $i+=2) {
                $prime=0;
                #Divide the number by all the prime numbers less than the square
 root
                $squareroot=sqrt($i);
                foreach $j (@primes) {
                        if ( $j > $squareroot ) {
                                last;
                        }
                        if (($i%$j) == 0) {
                                $prime=1;
                                last;
                        }
                }
                if ($prime == 0 ) {
                        $count+=1;
                        print "$count: $i \n";
                        push(@primes,$i);
                        if($count == $stop ) {
                                print "The $stop prime number is: $i \n";
                                exit(1);
                        }
                }
        }
}


Friday, November 4, 2011

Solution to Project Euler Problem 6 - sum of the squares of the first one hundred natural numbers and the square of the sum.

Problem: 
The sum of the squares of the first ten natural numbers is,
12 + 22 + ... + 102 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.
Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

Answer: 
The sum of the squares of the first ten natural numbers is:338350
The square of the sum of the first 100 natural numbers is: 25502500
The difference between the sum of the squares of the first ten natural numbers and the square of the sum is: 25164150

Solution:

#!/usr/bin/perl -w
use strict;
my ($i,$ulimit,$sosq,$sqos);
$ulimit=100;
print "The sum of the squares of the first ten natural numbers is:";
for ( $i=1; $i<=$ulimit;$i++ )
{
        $sosq+=$i*$i;
        $sqos+=$i;
}


print "$sosq \n";
$sqos=$sqos*$sqos;
print "The square of the sum of the first $ulimit natural numbers is: $sqos \n";


my $diff=$sqos-$sosq;
print "The difference between the sum of the squares of the first ten natural nu
mbers and the square of the sum is: $diff \n";



Tuesday, November 1, 2011

BUILD FAILED Unable to delete file hsqldb.out

Process Explorer shows you information about which handles and DLLs processes have opened or loaded.
  • Download Process Explorer from Microsoft site and run the program.
  • Click the Find menu, and choose Find Handle or DLL...
  • Type the file name (name of the file which is locked by some process.)
  • After typing the search phrase, click the Search button
You should see the list of applications which are accessing the file.

Solution to Project Euler Problem 5 - the smallest positive number that is evenly divisible by all of the numbers from 1 to 20

http://projecteuler.net/problem=5

Question:

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?

Answer: 232,792,560

Solution:
#!/usr/bin/perl -w
use strict;


my ($max,$i,$num,$found);
$max=20;
$num=2;
while($num) {
        $found=1;
        for ($i=2;$i<=$max;$i++)
        {
                print "$num%$i \n";
                if( ($num%$i) != 0 ) {
                        last;


                }else {
                        $found++;
                }


        }
        if($found == $max ) {
                print "The smallest number that can be divided by each of the nu
mbers from 1 to $max is:  $num \n";
                exit (0);
        } else  {
                $num++;
        }
}


Output:
The smallest number that can be divided by each of the numbers from 1 to 20 is:
 232792560

Solution to Project Euler Problem 4 - The largest palindrome made from the product of two 2-digit numbers and two 3-digit numbers

http://projecteuler.net/problem=4

What will you know in this perl script ?
1) How to split a number/string (like 123456) into an array?
2) How to convert array into string?
3) Perl's numerical sort function and the <=> numerical comparison operator
4) Finding uniq elements in an array using grep and hash
5) You will know how to generate palindromes



Question: 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.

Answer:  906609 (993 * 913)


Solution: 

#!/usr/bin/perl -w
use strict;


#Palindrome from 2 digit products
print "Palindromes from 2 digit products are ... \n";
generate_palindrome( 10, 99);
print "Palindromes from 3 digit products are ... \n";
#palindrome from 3 digit numbers
generate_palindrome( 100, 999);


sub generate_palindrome {
        my ($start, $end)=@_;
        my ($i, $j, $res,@number,@revers,$rev, @palindromes,@sorted, @unique, %s
een);
        for ($i=$start;$i<=$end;$i++) {
                for ($j=$start;$j<=$end;$j++) {
                        $res=$i*$j;
                        #Split a number into array
                        @number = ( $res =~ m/./g );
                        #reverse the array which stores the number
                        @revers=reverse(@number);
                        #convert array to string
                        $rev = "@revers";
                        #Replace the Extra separating spaces with blank
                        $rev =~ s/(.)\s/$1/seg;
                        #print "$i * $j = $res \n";
                        #print "Reverse: $rev \n";
                        if ( $res eq $rev ) {
                                #print "$res \n";
                                push (@palindromes, $res);
                        }
                }
        }


        #Perl's sort function and the <=> numerical comparison operator
        #The sort function takes an optional code block, which lets you replace
the default alphabetic comparison subroutine with your own.
        #This comparison function is called each time sort has to compare two va
lues.
        #The values to compare are loaded into the special package variables $a
and $b , which are automatically local ized.


        @sorted = sort { $a <=> $b } @palindromes;
        # Finding uniq elements in an array using grep and hash
        @unique = grep { ! $seen{$_}++ } @sorted;
        print "@unique\n";
        print "The largest palindrome is $unique[$#unique] \n";
}


Output: 
Palindromes from 2 digit products are ...
121 242 252 272 323 363 414 434 444 464 484 494 525 555 575 585 595 616 636 646 656 666 676 686 696 737 767 777 828 848 858 868 888 949 969 979 989 999 1001 1221 1551 1771 1881 2002 2112 2332 2442 2552 2772 2992 3003 3663 3773 4004 4224 4554 4664 4774 4884 5005 5115 5225 5335 5445 5775 6006 6336 6776 7007 7227 8008 8118 8448 9009
The largest palindrome is 9009
Palindromes from 3 digit products are ...
10201 11211 12221 12321 13231 13431 14241 14541 14641 15151 15251 15351 15651 15851 16261 16761 17271 17871 18081 18281 18981 19291 19591 20002 20202 20402 20502 21012 21112 21312 21412 21712 21812 21912 22022 22422 22922 23232 23432 23532 23632 23932 24442 24642 24742 25152 25252 25452 25652 25752 26062 26162 26462 26562 26862 26962 27072 27472 27572 27772 27872 27972 28182 28282 28482 28782 29192 29392 29492 29592 29792 29892 29992 30003 30303 30603 31313 31413 31613 3252332623 33033 33233 33333 33633 34243 34443 34643 34743 35453 35653 35853 35953 36663 36863 36963 37073 37373 37673 37873 37973 38383 38683 39093 39593 39693 39893 40004 40304 40404 40504 40704 40804 41114 41314 41514 41814 42024 42224 42624
42824 42924 43134 43434 43734 43834 44044 44144 44344 44444 44544 44744 44844 44944 45154 45254 45854 45954 46364 46464 46664 46764 46864 46964 47174 47674 47874 47974 48184 48384 48484 48884 48984 49494 49594 49794 49894 50005 50505 50605 51015 51315 51415 51615 51815 52125 52325 52425 52525 52625 52725 52925 53235 53535 53835 53935 54145 54945 55055 55255 55555 55755 55955 56165 56265 56465 56565 56865 57275 57375 57475 57575 57875 58185 58485 58685 58985 59095 59295 5949559595 59895 59995 60006 60306 60606 60706 61016 61116 61516 61716 62426 62526 62626 62726 62826 62926 63036 63336 63536 63736 63936 64246 64446 64546 64746 65056 65156 65556 65656 65856 66066 66466 66566 66666 66766 66866 67076 67176 67276
67776 67876 67976 68086 68186 68286 68486 68586 68686 68786 68886 69296 69496 69596 69696 69996 70007 70307 70707 70807 71117 71217 71817 72027 72627 72927 73337 73437 73537 73937 74347 74447 74547 74847 74947 75057 76167 76467 76867 77077 77677 77777 77877 78287 78387 78987 79097 79297 79497 79597 79797 79897 80008 80208 80408 80608 80808 80908 81018 81618 81718 81918 82128 82228 82328 82628 82728 82928 83538 83638 83738 83838 84048 84148 84348 84448 85058 85158 85358 86268 86668 86768 86868 87078 87178 87278 87478 87978 88088 88288 88688 88788 88888 89198 89298 89498 89598 89698 89798 90009 90109 90209 90909 91719 92129 92229 92329 92529 92629 92829 93639 93839 93939 94149 94249 95259 95559 95659 96369 96669
96869 97079 98189 98289 98489 98589 98789 98889 99099 99199 99299 99599 99699 99799 99899 99999 101101 102201 105501 106601 108801 110011 111111 117711 119911 121121 122221 123321 127721 128821 129921 131131 133331 135531 137731 138831 140041 141141 142241 143341 147741 149941 154451 155551 156651 159951 161161 162261 165561 168861 171171 174471 178871 180081 182281 184481 187781 188881 189981 198891 201102 202202 204402 209902 210012 212212 213312 214412 215512 216612 219912 220022 221122 222222 225522 227722 231132 232232 234432 235532 238832 239932 242242 244442 246642 249942 252252 255552 256652 257752 258852 259952 262262 266662 270072 272272 273372 276672 277772 279972 280082 282282 284482 286682 289982 290092 292292 294492 296692 297792 299992 301103 302203 303303 306603 308803 320023 321123 324423 329923 330033 333333 335533 343343 345543 348843 354453 357753 359953 363363 366663 367763 369963 371173 372273 374473 375573 377773 378873 384483 391193 393393 397793 399993 401104 402204 404404 405504 407704 408804 409904  412214 414414 416614 420024 421124 424424 425524 426624 428824 432234 434434 436634 438834 440044 441144 442244 443344 444444 445544 447744 452254 456654 459954 461164 462264 464464 468864 469964 470074 471174 474474 476674 477774 484484 485584 487784 488884 489984 491194 493394 505505 506605 507705 508805 509905 510015 512215 513315 514415 515515 519915 520025 522225 523325 525525 528825 531135 534435 535535 536635 543345 545545 548845 549945 550055 551155 554455 555555 560065 561165 564465 565565 570075 571175 573375 575575 576675 577775 579975 580085 585585 588885 589985 592295 595595 601106 602206 603306 604406 606606 611116 612216 616616 618816 619916 623326 630036 631136 636636 639936 642246 648846 649946 650056 652256 653356 654456 656656 657756 660066 661166 663366 666666 672276 675576 678876 689986 693396 696696 698896 723327 729927 737737 747747 749947 770077 780087 793397 801108 802208 804408 807708 809908 819918 821128 824428 828828 840048 853358 855558 861168 886688 888888 906609
The largest palindrome is 906609 (993 * 913 )

Solution to Project Euler Problem 3 - Finding prime numbers till trillion and largest prime factors for a large number (over 6 billion)



I wrote the most processing power consuming script of my life. It's running from last 7 hours, till not completed !!! 
What you will know in this script? 
A optimized (to best of my knowledge) perl function to generate prime numbers.
Perl module to find square root.
How to find prime factors for a given number.
How to screw up your CPU :)

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

Solution:

#!/usr/bin/perl -w
use strict;
use Math::Complex;
my (@primes,$ulimit);
$ulimit=600851475143;
generate_prime();
prime_factors($ulimit);


sub prime_factors {
        my ($num)=@_;
        my (@prime_factors,@sorted);
        print "Prime factors of $num are \n";
        foreach(@primes) {
                if ( $_ > $num ) {
                        last;
                } else {
                        if ( ($num%$_) == 0 ) {
                                push(@prime_factors,$_);
                        }
                }
        }
        @sorted = sort { $a <=> $b } @prime_factors;
        print "@sorted \n";
        print "The largest prime factor of $num is: $sorted[$#sorted] \n";
}


sub generate_prime {
        my ($i,$j,$prime,$squareroot);
        @primes=(2,3,5,7);  # Initializing known prime numbers
        #We know only 2 is the even prime numbers, hence skip all even numbers
        for ($i=9;$i<=$ulimit; $i+=2) {
                $prime=0;
                #Divide the number by all the prime numbers less than the square root
                $squareroot=sqrt($i);
                foreach $j (@primes) {
                        if ( $j > $squareroot ) {
                                last;
                        }
                        print "$i: $i%$j\n";
                        if (($i%$j) == 0) {
                                $prime=1;
                                last;
                        }
                }
                if ($prime == 0 ) {
                        print "$i \n";
                        push(@primes,$i);
                }
        }
        print "@primes \n";
        open (FH, ">prime-numbers.txt") || die "Cant create prime-numbers.txt $!";
        print FH "@primes\n";
        my $len=@primes;
        print "Total number of prime numbers from 1 to $ulimit= $len \n";
}