Saturday, April 16, 2011

Portal 2

Portal 2 drops anytime between now and Tuesday morning. I say anytime between them as Valve has given its fans a chance to play a bunch of indie games that they are promoting (and in turn the indie games had a hand in promoting Portal 2) to help unlock an earlier release time on Steam.

Current time release countdown as well as games that still need playtime can be found here:
http://www.aperturescience.com/glados@home/

Further information can be found on Reddit

In their anticipation a good friend of mine baked a Portal cake for her son. I think she had fantastic results. I only regret that I was not able to partake of the cake myself. Full Image here

Wednesday, April 13, 2011

Problem 4

Problem 4:
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.
Initial Thoughts:
As usual this problem has a couple of different layers to it. The first order of business is to figure out how to reverse a number and then compare it to the original number. The second order of business is to test each number from 100 to 999.

Multiplying the two digits is the easy part of this question, I'll just nest a for loop in another to multiply x by y until y hits 999, then increase x once and start over for y. Checking the product of x and y to determine if it is a palindrome is the difficult part.

My breakthrough came after a bit of brainstorming and bouncing some questions off of a friend. His hint of write down a sample palindrome down on paper and really thing about the steps you do to reverse the number by hand. So what I do of course is on a new line and take the last digit and write it down first on this new line. I then add the next to last digit to the new line and so one until the end of the number. Then compare the two numbers. Now obviously you can eyeball it and tell instantly when it's down on paper, but really stepping back these are the steps one is taking.

This means I will need to know the length of the product of x and y and create a loop to take the last digit and add that digit to a new variable (the "new line") until I run out digits. I will also need to multiply the number I moved by 10^(remaining digits in the original string) to keep the correct power of the number. It occurs to me that I could attempt to convert each number into a string and reverse the string, but what's the fun in that? I'm going to complete this problem via math related functions only. If you prefer converting to a string first you can find many options by searching for "reverse a string in c#". Easiest solution I saw was to store the string as an array then reverse the array. Done.

Final Thoughts:
In the end this problem becomes easy once you realize you can use mod to move the decimal place over to the left and keep the remainder. Multiply this remainder by 10^(however many digits are left), store the new number as a variable, then compare. Each step check to see if the number is a palindrome then store the number if it is greater than the last successful palindrome.

The code takes about 1.3 seconds to run - which I'm not thrilled with but is still well under the one minute time limit set by PE. I'm still curious if there is a way to speed this up. I know that if either x or y end in a zero the resulting number will not be a palindrome. I never implemented this however as at most I'd expect a 10% gain.

Solution Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 1;
            int y = 1;
            double z = 0;
            double prodxy = x*y;
            double varlen = Math.Ceiling(Math.Log(prodxy) / Math.Log(10));  //Finds the length of the number
            double paldr = 0;
            double maxpaldr = 0;
            int maxx = 0;
            int maxy = 0;

            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            for (x = 100; x < 1000; x++)
            {
                for (y = 100; y < 1000; y++)
                {
                    prodxy = x * y;
                    varlen = Math.Ceiling(Math.Log(prodxy) / Math.Log(10)); //Finds the length of the number
                    paldr = 0;
                    for (z = varlen; z > 0; z--)
                    {
                        paldr = paldr + ((Math.Pow(10, z - 1)) * (prodxy % 10));
                        prodxy = Math.Floor(prodxy / 10);
                    }
                    if (paldr == (x * y) && paldr > maxpaldr)
                    {
                        maxpaldr = paldr;
                        maxx = x;
                        maxy = y;
                    }
                }
            }

            stopWatch.Stop();

            Console.WriteLine("Answer: " + maxx + " * " + maxy + " = " + maxpaldr);
            Console.WriteLine("Elapsed Time: " + stopWatch.ElapsedMilliseconds + " ms");
        }
    }
}

Thursday, April 7, 2011

Problem 3

Problem 3
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Initial Thoughts:
I had to do a bit of catching up on how to identify Prime numbers. A Prime is a number only divisible by 1 and itself. The question becomes how do we check this outside of a "brute force" method in which you just loop each subsequent number from one until the number we are checking. Especially when staring at the absurdly large number requested in the Problem.

This problem and any Prime number questions after it will come down to saving CPU cycles to more quickly and efficiently check for prime.

Right off the bat we realize that beyond the number 2, a prime will can only ever be an odd number. This alone cuts out half the numbers we will need to check for prime. We will simply start with an odd number and add two each loop iteration to keep the number we are checking odd.

Doing some further research and we will discover that the highest possible factor of a number will be equal to or less than the square root of that number (sqrt). As taking the sqrt of a number multiplied by itself will equal the whole number again. Thus our loop can simply be from one to the sqrt of the number. This enormously reduces the number of iterations our loop will need.

To illustrate further:
sqrt(100) = 10. which is 10% of 100.
sqrt(1000) = 31.622 or 3.162% of 1000
sqrt(10000) = 100 or 1.00% of 10000
sqrt(100000) = 316.227 or .3162% of 100000
sqrt(1000000) = 1000 or 0.1% of 1000000
sqrt(10000000) = 3162.27 or 0.03162% of 10000000




Look at the percentage of each number we need to check as you increase the number size. We can also see a logarithmic pattern develop.Now that we have our CPU cycle savings methods in place lets look at the rest of the question. First thing we will touch on is the sheer size of the number PE is asking us to look at.

Signed vs Unsigned data types:
For our purposes we need to know that a Signed data type can store both positive and negative numbers. Whereas an Unsigned data type can only store positive values. An INT data type is able to store 2^32 bits of data: 4,294,967,296. However because it is a Signed data type and can store negative numbers our INT data type is only able to store values between -2,147,483,648 to 2,147,483,648.

Problem 3 has us looking at a number up to 600,851,475,143 which obviously exceeds INT's capacity. I should mention to set a variable to the unsigned int type simple use "UINT" (or Unsigned INT). IE. UINT x;

int64 / long:
INT64 or LONG (I will be using LONG as I've grown accustomed to this nomenclature) stores 2^64 bits of information. They can store 18,446,744,073,709,551,616 bits of data! We should still be careful of Unsigned vs Signed data types, but even a Signed LONG will be able to store the number we are analyzing.

Final Thoughts:

I will be setting long x equal to 600851475143
I want to loop from 3 to the sqrt of x. I will be adding 2 to each loop cycle so we are only checking odd numbers. Any time the loop finds an evenly divisible number I will break the loop and output those results.
I will need a special if statement to handle a number being divisible by two.
This should provide us the least common prime least common denominators.
Solution Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            long x = 600851475143;
            int y;
            int z = 1;
            int zz = 1;
            int numend = 1;
            
            Console.WriteLine("Prime Factors: ");
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            while(numend ==1)
            {
                numend = 0;
                if (x % 2 != 0)
                {
                    z = 0;
                    for (y = 3; y <= Math.Sqrt(x) && z < 1; y = y + 2)
                    {
                        if (x % y == 0)
                        {
                            Console.Write(y + ", ");
                            x = x / y;
                            z = 1;
                            numend = 1;
                        }
                    }
                }
                else
                {
                    Console.Write("2, ");
                    x = x / 2;
                    numend = 1;
                }
                zz++;
            }
            stopWatch.Stop();
            Console.WriteLine(x);
            Console.WriteLine("Elapsed Time: " + stopWatch.ElapsedMilliseconds + " MS");
        }
    }
}

Tuesday, April 5, 2011

Problem 2

Problem 2:

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.
Alright so we're going to need to again keep a running total with the extra twist of only adding the even valued terms. The Fibonacci sequence is of course 1 + 1 = 2, 1+2 = 3, 2+ 3 = 5, 3 + 5 = 8 and so forth. So we can see that it is taking the preceding two numbers in the sequence and adding them together to get the next digit in the sequence. Then moves over one and adds the two digits to come up with the next digit in the sequence, so on and so forth. So we will need to replicate the Fibonacci sequence until it's value is greater than 4,000,000 doing a mod 2 each time to determine if the digit is even.

I'm curious if there is a better way to determine if a number is even, but a quick mod 2 appears to run fast enough. Speaking of Project Euler in general states that each question should take less than a minute to return. So it occurs to me to see if I can get a system timestamp before the code and then a timestamp after the code is done running. Take that delta and return the elapsed time. In my search I discovered C# is awesome and has a built in function to do just that!

Stopwatch Function:
More info can be found on MSDN. First thing we need to do is include System.Diagnostics. This is the package that includes this nifty little function. Then to utilize it I set a variable to the function. I named the variable stopWatch according to their example:
Stopwatch stopWatch = new Stopwatch();
The to start the stopwatch you simply call the variable and use it's built in start function (ie stopWatch.Start();). Watch your capitalization here. stopWatch is your variable whereas Stopwatch is the function that you set your variable to.

Onto the code for Problem 2.This time I used a While Loop to look at my sequence 2 variable to make sure it didn't exceed 4,000,000.

While Loops:
While (variable is some condition)
     {
          do stuff
     }
So I will set my first sequence to 0 and my second sequence to 1. add them into a temporary variable, check if that temporary variable is an even number. If it is add it to my running total. Then set the 1st sequence to the 2nd sequence and the second sequence to the temporary variable. Repeat as long as we're under 4,000,000.  I have my stopWatch set and to output the time lapsed in milliseconds (stopWatch.ElapsedMilliseconds).

Solution Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int seq1 = 0;
            int seq2 = 1;
            int tempseq = 0;
            int total = 0; 
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            while(seq2 < 4000000)
            {
                tempseq = seq1 + seq2;
                if (tempseq % 2 == 0)
                    total = total + tempseq;
                seq1 = seq2;
                seq2 = tempseq;
            }
            stopWatch.Stop();
            Console.WriteLine("The Answer is: ");
            Console.WriteLine(total);
            Console.WriteLine(stopWatch.ElapsedMilliseconds);
        }
    }
}
The Code comes back with the correct answer and the time lapsed in milliseconds is ZERO! Well I'd say that's under a minute so this problem is complete.

Still working on making that code paste look pretty.

Problem 1

Problem 1: 
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
If you recall - natural numbers are simply positive whole numbers (no decimals!).So my first impression as to tackling this problem is to loop a number from 1 to 999 and divide by 3 and 5 along the way. Anything that divides with no remainder goes evenly into the number and should be added to a running total.


Ok, sounds easy enough. but i'll need to know what the syntax is for a for loop and an if statement.


For Loop syntax:
for (initial condition variable; condition is some circumstance; increment the original variable to progress through the loop). 



Lets look at an example and use the knowledge that we need to loop from 1 to 999


Example:
for (x = 1; x <= 999; x++)
    {
        do stuff here
    }
If Statement syntax:
if (variable <operator> equals result)
Example:
if(x%3 == 0)
     {
          do stuff
     }
Mod command:
Now the "%" symbol is called mod. The mod command returns the remainder of the division of x divided by 3. This is useful to us in this question to check if 3 or 5 goes evenly into x.

Or Command:
Double pipe "||" is the or statement in C#, we'll be using that to see if x%3 or x%5 is 0.

So my entire code solution for this problem is:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 1;
            int y = 0;
            for (x = 1; x < 1000; x++)
            {
                if (x % 3 == 0 || x % 5 == 0)
                    y = y + x;
            }
            Console.WriteLine("The Answer is: ");
            Console.WriteLine(y);
        }
    }
}
This seems to run pretty darn fast and outputs the correct statement. I've chosen to run a console application from the projects window and use Crtl + F5 to have the console window stay open after I run the code.

I will work on better code formatting in future posts but as you can see we're simply looping from 1 to 999 and dividing by 3 and 5 at each loop. If the remainder is zero we add it to our running total variable of "y".

Euler Project

This is a place where I discuss my solutions to Project Euler. This is a side project I've picked up as something fun to do while learning a new skill set. I originally started PE using php and quickly discovered php can be quite a bit slow on some of these problems. I then hopped to Javascript as it's ubiquitous and easy to use. I eventually ran into problems with how large some of the numbers are that you end up working with. From there I polled two friends that do dev work and asked each "If I were to learn a new language while doing PE, would you recommend Java or C++ to me. Both said (independently) C#.

So begins my journey of attempting to tackle Project Euler while learning a new language - though I say new and I honestly haven't programmed anything outside of Visual Basic circa 1999. 

I hope you find some of my solutions helpful and welcome any critiques as I proclaim absolutely no expertise in either the math behind some of these problems nor finesses in C#.


For the record I'm using Microsoft's Visual Studio Express 2010 for C# for my IDE.