Wednesday, December 8, 2010

How to get around pesky registration sites

It occurred to me today that many people encounter the same troubles as me with web sites that insist on you registering, but that you may not know how to best circumvent them.  The more you give out your email, the more spam you get, so don't do it anymore.

When I come across a registration site I want access to, the first place I check is bugmenot.com.  You enter the site's url into their search bar and they'll give you the login information they have stored.  Unfortunately, bugmenot tends to bend to legal pressure rather easily and are missing a lot of sites.

Next, if that didn't do it, try registering with an email address from mailinator.com/. This site is brilliant and will store any mail sent to it for you (including confirmation emails).  Now you should be able to get a working account and, if you want to be a really good person, you can put the information up on bugmenot (assuming it isn't one of their banned sites).

You should know that some clever webmasters will know about mailinator and won't let you register using them.  In this case, try the lesser-known equivalent dodgit.com/.  It'll work just as well.

If you know of any alternatives to bugmenot, leave a comment.  I'd love to know.

Monday, December 6, 2010

Euler in LISP, Oh my God!

I've spent the past several hours struggling to solve Project Euler problem 30 in LISP.  I want to die.

There were a few moments early in my code writing where I was enamored by how much was being done in so few lines, but the rest of the time was spent screaming profanity at my computer screen when I couldn't get even the simplest of things to work.

In the end, once I'd found the numbers I needed, I added them together with a calculator just to avoid writing another line of LISP.

 Since I know my code is a mess, I'm just going to include the code that calculates the sum of a number's digits to the P'th power.


(defun funSum (N P)
           (if (= N 0)
               0
               (+ (power (rem N 10) P) (funSum (values (floor N 10)) P))))

First, the functions in this program.

power: I had to write my own power function.  Returns N^P. See the code below.
(defun power (N P)
           (if (= P 1)
               N
               (* N (power N (- P 1)))))
rem: this returns the remainder of the first number divided by the second.  It's the equivalent of num1%num2

floor: this divides the first number by the second and rounds down to the nearest integer.

values: This isn't actually necessary for the code to work.  The idea is, the floor function actually returns two numbers, only one of which we need.  The values function suppresses the second number returned by floor.

funSum: This is the entire section of code you see above.  It calls itself inside itself (a programming technique known as recursion).  recursion is also used in the power function above.

Translation of funSum with N = 4151 and P = 5

if 4151 = 0, return 0

4151 != 0, so return (((4151%10)^5 + this whole process again with N = 4151/10 and P = 5)

the math in the last line:
4151%10 = 1
1^5 = 1
4151/10 = 415  <- note that we get rid of any decimal we get

Simplified, the last line is
return (1 + the whole process again with N = 415 and P = 5)

Then we do it all over again with N = 415 and P = 5 until we run out of digits.

That's recursion for you.  In LISP, it's everywhere.

Wednesday, December 1, 2010

Coding Journey, Euler Problems 16, 20, 25 and 48

So, I worked on Project Euler problems 16, 2025 and 48 over the break.  The entire idea of each of these problems is that the numbers involved get way too big for the program to store, so you have to get creative with the number storage.

I decided to store the obscenely large numbers in an array of integers.  Then, I needed some way to manipulate the array so that we can add to and multiply numbers into it.  All of my solutions to these problems revolve around the following functions:



//assigns source to target
void assign(int target[], int length, int source[])
{
        for(int k = 0; k < length; k++)
        {
                target[k] = source[k];
        }
        return;
}

//Had to alter from problem 48.
void add(int number[], unsigned& lengthNum, int add[], unsigned lengthAdd)
{
        int remainder = 0;
        int temp;
        unsigned k = 0;
        //Adds the arrays together until one or the other array ends
        for(k = 0; k < lengthNum && k < lengthAdd; k++)
        {
                temp = (number[k] + add[k]);
                number[k] = (temp + remainder)%10;
                remainder = (temp + remainder)/10;
        }
        //the following deals with adding the rest of the arrays together once they diverge
        //if lengthAdd ended first
        if(k < lengthNum)
        {
                while(remainder > 0 && k < lengthNum)
                {
                        number[k] = (remainder%10+number[k]);
                        remainder /= 10;
                        k++;
                }
        }
        //if lengthNum ended first
        else if(k < lengthAdd)
        {
                while(remainder > 0 && k < lengthAdd)
                {
                        number[lengthNum++] = (remainder%10+add[k]);
                        remainder /= 10;
                        k++;
                }
        }
        //deals with the remainder
        while(remainder > 0)
        {
                number[lengthNum++] = remainder%10;
                remainder /= 10;
        }
        return;
}

//multiplies the multiplier into the array
void mult(int number[], unsigned& length, const unsigned multiplier)
{
        int temp;
        int remainder = 0;
        //does the multiplying
        for(unsigned k = 0; k < length; k++)
        {
                temp = multiplier*static_cast<int>(number[k]);
                number[k] = (temp+remainder)%10;
                remainder = (temp+remainder)/10;
        }
        //deals with the remainder
        while(remainder > 0)
        {
                number[length++] = remainder%10;
                remainder /= 10;
        }
        return;
}

//adds all the digits in the array together
long sumOfDigits(const int number[], const unsigned length)
{
        long retVal = 0;
        //adds each character together
        for(unsigned k = 0; k < length; k++)
        {
                retVal += static_cast<int>(number[k]);
        }
        return retVal;
}

//prints out the array as a number
void out(int number[], const unsigned length)
{
        cout << "Number: ";
        //prints out each character in reverse order
        for(int k = length - 1; k >= 0; k--)
        {
                cout << static_cast<int>(number[k]);
        }
        cout << endl;
}

I have the individual solutions to the problems, if anyone's interested. Just leave a comment if you have any requests.