Archive for the 'Computers' Category

JavaScript: faster zero-padding

January 20th, 2009

While fooling around with some JavaScript for a number formatting function at work, I stumbled upon this result.

It is faster to pad a string with zeros using array joins rather than the conventional for-loop. Here’s what I tested with.

var N=1000000, start, end;

// Using for-loop
start = new Date().getTime();
var j = '1';
for (var i=0; i<N; i++) {
    j += '0';
}
end = new Date().getTime();
console.log(end-start);

// Using Array join
start = new Date().getTime();
var k = '1';
k += new Array(N+1).join('0');
end = new Date().getTime();
console.log(end-start);

The results show that on average, using a for-loop took 1200ms, while the Array.join() took 200ms. That’s a significant improvement! The Array.join() method takes 1/6 of the time, and this result seems consistent across different values of N.

Being a little bit cautious about the results, I wanted to make sure that Array.join() is practical in normal usage. I mean, when would you ever need to append a bijillion zeros to your number? So I modified the test a little bit, and here’s what I came up with.

var N=10000, M=10, start, end;

// Using for-loop
start = new Date().getTime();
for (var k=0; k<N; k++) {
    var j = '1';

    for (var i=0; i<M; i++) {
        j += '0';
    }
}
end = new Date().getTime();
console.log(end-start);

// Using Array join
start = new Date().getTime();
for (var k=0; k<N; k++) {
    var j = '1';
    j += new Array(M+1).join('0');
}
end = new Date().getTime();
console.log(end-start);

The results for the second test showed that Array.join() is still faster, with for-loop running in about 140ms and Array.join() at 85ms — for M=10.

However, it seems that the two methods are about even at M=4, and for-loop is faster for M<4, and Array.join() is faster for M>4.

So what can we take from this? I guess you’ll have to evaluate each problem on a case-by-case basis. If the average use case means a lot of zeros being padded, then Array.join() is hands-down the winner. However, if the average use case calls for less zeros to be appended, then it might be better to stick to the for-loop method. Although, at M=1, the Array.join() ran about double the time of the for-loop, which isn’t horrible.

I hope this will help some people. :)

Note: This method can apply to any cases where padding the same string x amount of times to an existing string occur.

Do you mean partial application?

December 8th, 2008

As I’ve been digging through more functional programming techniques, I often see people mention Curry functions. As it turns out, when a lot of people say “curry” they really mean Partial Application. For example, this page here about curry implementation in Python, or implementations in JavaScript. I did find one implementation in JavaScript that worked, but it’s rather long.

I came up with my own implementation in less than 10 lines of JavaScript code. Before I show it though, let’s define what we should expect. The follow are the JavaScript code we’re going to run, and the expected output are in the comments.

function add(a, b) {
    return a + b;
}

function add5(a, b, c, d, e) {
    return a + b + c + d + e;
}

function saySomething(x, y, z) {
    alert(x + y + z);
}

add.curry()(4)(6);
//--> 10

add5.curry()(1)(2)(3)(4)(5);
//--> 15

add5.curry()(1)(2);
//--> function with one parameter

add5.curry()(1)(2)(3)(4)(5)(6);
//--> TypeError: add5.curry()(1)(2)(3)(4)(5) is not a function

saySomething.curry()('Hello ')('World! ')('foo bar');
//--> Alert mssage "Hello World! foo bar" pops up

Remember that currying a function, say f:(X x Y) –> Z means that curry(f):X –> (Y –> Z). And for a function g with n arguments, curry(g) transforms the function g into a chain of n functions that each take exactly one argument.

So here is my implementation of the curry function.

Function.prototype.curry = function() {
    var savedArgs = [],  n = this.length, func = this;

    return (function(x) {
        savedArgs.push(x);
        if (savedArgs.length < n) return arguments.callee;
        else  return func.apply(null, savedArgs);
    });
};

Note that is utilizes anonymous functions in JavaScript, which recursively calls itself using the arguments.callee reference.

Publisher/Subscriber Fun with jQuery

December 5th, 2008

I’ve decided to try out the Publish/Subscribe pattern for some of the new things we’re creating at work. So far I think it’s working out really well. The neatest thing is that a Pub/Sub system can be created in JavaScript in very little amount of code. And with the help of jQuery, you can shorten the amount of code even more.

Here is the entire system in jQuery.

jQuery.subscribe = function(signal, scope, fnName) {
    var curryArgs = Array.prototype.slice.call(arguments, 3);
    $(window).bind(signal, function () {
        var normalizedArgs = Array.prototype.slice.call(arguments, 1);
        scope[fnName].apply(signal, curryArgs.concat(normalizedArgs));
    });
    return jQuery;
};

jQuery.publish = function(signal) {
    $(window).trigger(signal, Array.prototype.slice.call(arguments, 1));
    return jQuery;
};

Notice that the subscriber function allows for partial applicationof the handler function. This can be useful in some cases.

Project Euler: Problem 2

November 18th, 2008

An elegant solution to the Fibonacci problem.

from math import sqrt, pow

def fib(n):
    phi = (1 + sqrt(5))/2
    return int((pow(phi, n) - pow(1 - phi, n))/sqrt(5))

if __name__==’__main__’:
    i = 3
    sum = 0
    stop = 4000000

    while True:
        curr = fib(i)

        if curr > stop: break

        sum = sum + fib(i)
        i = i + 3
    print sum

Unlike the other solutions I found online, mine is not done through brute-force. To generate the Fibonacci number at index i, you don’t need to loop through the sequence until i. There is a closed form solution to this. For even-numbers in the sequence, it’s rather simple. An even number occurs with index 3, 6, 9, 12, 15, … Notice a pattern? I hope you do. :)

Project Euler: Problem 28

November 10th, 2008

Thought I’d post up my solution to Problem 28 on Project Euler.

After the answer was submitted I read through some of the other code the people have posted. It seems that there are a lot more programmers than mathematicians because almost all of the solutions were brute-force algorithms… and quite a few were written in assembly. *shrug*

Anyway, here is the problem.

Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:

21 22 23 24 25
20  7  8  9 10
19  6  1  2 11
18  5  4  3 12
17 16 15 14 13

It can be verified that the sum of both diagonals is 101.

What is the sum of both diagonals in a 1001 by 1001 spiral formed in the same way?

The first you to notice is that you don’t have to actually construct the spiral in order to solve this problem. It can be shown quite simply that in an nxn spiral, the values of the four corners are as follows:

top-right: n^2
top-left: n^2 - n + 1
bottom-left: n^2 - 2n + 2
bottom-right: n^2 - 3n + 3

Adding all that up yields 4n^2 -6n + 6.

At this point you can easily loop through from 3 to 1001 (in increments of 2) and add up the results. Just make sure you add a 1 to the results for the base case. :)

Of course, if you’re like me you wouldn’t be satisfied with that result. All we’re dealing with are some simple summations, so the result for an nxn spiral should be easily expressed by a formula. In fact, here’s the formula.

Sum(i = 1:500)[4(2*i + 1)^2 - 6(2i + 1) +6]

The beginning reads “sum from i=1 to 500″… I’m not too sure how to type out sigma notations properly.

Converting the summation into closed form gives the formula we’re looking for. I’m leaving out the steps, but it’s fairly simple anyway.

(16n^3)/3 + (10n^2)/2 + 26n/3

And here is the complete solution in Python.

from math import pow
def prob28(n): return (16*pow(n, 3) + 26*n)/3 + 10*pow(n, 2)
print prob28(500) + 1

Project Euler

November 10th, 2008

I came across this interesting project online. It’s called Project Euler, and the point is to use both mathematical skills and programming skills to solve the posted problems. You can use whatever language to solve, and you input the answer to validate it. So far I’ve worked on the very first one, and it’s pretty fun, both from a programming perspective, and from a math geek POV.

Here’s my solution to Problem 1:

Problem: Add all the natural numbers below one thousand that are multiples of 3 or 5.

Solution (Python):
reduce(lambda x,y: x+y, ifilter(lambda x: x%3==0 or x%5==0, range(1,1000)))

:)

Saving with Greasemonkey

August 10th, 2008

I have a high-interest savings account open, which is where I put all my savings into — dur. The only problem is that when I sign on to internet banking, I can see all my accounts listed there. A few times in the past I actually took money out from my savings account to pay off my credit cards. Well, most of the time it’s because I transferred too much into my savings without realizing I need that money for my credit cards.

I read some tips online about setting up automatic transfers to transfer x amount of money from your cheque into your savings, everytime you get a paycheque. This way you can fool your self to think that you have less money than you actually do. The only problem is that the tip only works if you’re transferring to another bank, like ING. Since I see my money listed there anyway, it’s almost pointless.

That’s where Greasemonkey comes in! Using some JavaScript, I hid my Savings account from the accounts view. Of course, I put in at link that I can click on if I do need to see it. I think it’s going to work well. :)

What Have I Been Doing?

August 5th, 2008

It’s been a really long time since my last post. Just haven’t had the urge to blog these days. It’s getting really busy at work with a bunch of different projects. That probably adds to my laziness when I get off work.

No, I’m just kidding. I’ve been doing quite a bit in the past little while actually. Aside from the regular house cleaning and cooking tasks, Ams’ and I have started planning our wedding. We even set up a little wedding blog for it!

You might notice the wedding blog is a Django site (so says the little button at the bottom). It’s coded by yours truly, Mr. Jack Hsu. I’ve actually released the code on Google Code with the New BSD License. So if you have Django running somewhere and wanna check out the blog app, please feel free to do so. It’s still a work in progress, and I’ve been working hard the last week or so to get the code ready for public consumption. The documentation is coming along as well!

I <3 Django!

Firefox 3.0 Released Today

June 17th, 2008

Firefox 3.0 has officially been released today. The Mozilla Foundation aims to set a world record with the most downloaded software in 24 hours. FF 3.0 makes huge improvements to memory usage, and also javascript execution. Go to the official site to download the installation file.

Want to get the most out of FF 3.0? Check out Lifehacker’s full coverage on the release, including top 10 new features!

Enjoy!

Robocup: Humanoid Finals 2007

June 5th, 2008

I just love watching Robocup. This one is especially impressive. I love how the goalie for Osaka dives to block shots. I laughed quite a bit while watching this clip.