Archive for the ‘Erlang’ Category

How I beat Project Euler using Erlang: Christmas Edition, problem one

Merry Christmas everyone!

It’s been a long time since I wrote a post, but I’ve been very busy coding, and I could only muster some posts for Stacktrace, so express all your Christmas-y goodness and pardon me :)

On Stacktrace we just started posting in depth analysis of the Project Euler problems, and I decided to try and solve them using Erlang, since I already did using Ruby a couple of years ago.

The first problem is quite simple:

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.

I will not try to give you the clever solution since this problem is quite simple, and the brute force solutions works fine :)

-module(p1). 
-export([sum_mul/1]). 
 
sum_mul([H|T]) -> valid(H) + sum_mul(T);
sum_mul([]) -> 0.
valid(H) when H rem 3 =:= 0; H rem 5 =:= 0 -> H;
valid(H) -> 0.

To get the solution just call _sum_mul(lists:seq(1,999))_.

Have a Merry Erlang Christmas!

Erlang, Ruby and PHP battle it out!

Update: here’s the followup!

Yesterday I attended PHP Day, in the beautiful city of Verona, and while going there by train, together with my friend Federico Feroldi, I told him that in a test I made a week ago Erlang was much slower than ruby in finding pythagorean triplets.

That was a partial lie, since the ruby implementation was somewhat optimized, while the erlang implementation wasn’t at all. So we decided to rewrite both programs using the same optimized algorithm and then test their speeds.

This is the ruby implementation of a method that counts the number of pythagorean triplets up to N:

def pythag(n)
  result = []
  (2..n).each do |c| 
    (1...c).each do |b|
      a = Math.sqrt(c*c - b*b)
      result << [a.to_i, b, c] if a.to_i == a 
    end
  end
  result
end

Then we coded it in Erlang. The code I’m going to show you is more complex than the ruby code because we took advantage of the parallelization features of the Erlang language:

-module(pythag).
-export([bard/1, pbard/1]).
 
my_is_integer(X) ->
  round(X) == X.
 
pbard(N) ->
  pmap(fun(C) -> 
              [
               {C, B, trunc(A)} || 
                B <- lists:seq(C, N), 
                A <- [math:sqrt(C*C + B*B)], my_is_integer(A) 
              ]
            end, 
            lists:seq(2, N)).
 
bard(N) ->
  lists:map(fun(C) -> 
              [
               {C, B, trunc(A)} || 
                B <- lists:seq(C, N), 
                A <- [math:sqrt(C*C + B*B)], my_is_integer(A) 
              ]
            end, 
            lists:seq(2, N)).
 
pmap(F, L) -> 
  S = self(), 
  %% make_ref() returns a unique reference 
  %% we'll match on this later 
  Ref = erlang:make_ref(), 
  Pids = lists:map(fun(I) -> 
                    spawn(fun() -> do_f(S, Ref, F, I) end) 
             end, L), 
  %% gather the results 
  gather(Pids, Ref). 
 
do_f(Parent, Ref, F, I) -> 
  Parent ! {self(), Ref, (catch F(I))}. 
gather([Pid|T], Ref) -> 
  receive 
    {Pid, Ref, Ret} -> [Ret|gather(T, Ref)] 
  end; 
gather([], _) -> 
  [].

The pythag function has been named bard, as in The Bard :)
The pbard function fires up a thread for each iteration of the outer loop and then gathers all the result back. This allows for up to 50% performance increase when using dual core CPUs (like my Macbook Pro :) ).

Once we coded it in two languages we couldn’t stop, so here’s a PHP implementation, a Javascript one and, last, but not least, a C implementation, because you can never forget C when you need speed :)

PHP:

<?php
$i=0;
 
for ($c = 2; $c <= 5000; $c++) {
  for ($b = 1; $b < $c; $b++) {
    $a = sqrt($c*$c - $b*$b);
    if (is_int($a)) {
      $i++;
    }
  }
}
print("$i");
?>

JavaScript:

function pythag(n) {
  var a,b,c,i
  for (c = 2; c <= n; c++) {
    for (b = 1; b < c; b++) {
      a = Math.sqrt(c*c - b*b);
      if (Math.floor(a) == a) {
        i++;
      }
    }
  }
  return i;
}

C:

#include <stdio.h>
#include <math.h>
 
#define MAX 5000
 
int main() {
  double c, b;
  int i = 0;
  double a;
 
  for (c = 2; c <= MAX; c++) {
    for (b = 1; b < c; b++) {
      a = sqrt(c*c - b*b);
      if (trunc(a) == a) {
        i++;
      }
    }
  }
  printf("%d\n", i);
}

To test the various relative speeds I ran them from the shell using time (php ruby and c), or used the internal timer (erlang), or ran them in firefox (js only actually).

The results were interesting. At the first run, using 5000 as N in the pythag functions the order was:

  1. C (obviously): 0.40s
  2. Erlang (smp): 3.95s
  3. Erlang (non-smp): 5.66s
  4. Ruby: 15.31s
  5. PHP: 19s (or so)
  6. Javascript: couldn’t even finish running because firefox said it was taking too much time

Fullo passed by and asked what we were doing, I told him I was testing languages and that PHP was dog-slow. He said it couldn’t be and asked me what version of PHP I was using. I checked and it was PHP 4.x.x.

After downloading and compiling PHP5 I ran the tests again and the final result was this:

  1. C (obviously): 0.40s
  2. Erlang (smp): 3.95s
  3. Erlang (non-smp): 5.66s
  4. PHP5: 8.9s (or so)
  5. Ruby: 15.31s
  6. Javascript: couldn’t even finish running because firefox said it was taking too much time

Now the numbers make sense. Doing these comparations was a nice experience, because when you implement the same thing in different languages you always learn something about optimization and code beauty.

Learning Erlang: The Beautiful Quicksort

Sometimes you really have to stop and contemplate how beautiful code is. This is an erlang quicksort algorithm, one of the most efficient (if I remember correctly it’s the most efficient) sorting algorithms. I still remember the pains of implementing it in C.

qsort([]) -> [];
qsort([Pivot|T]) ->
	qsort([X || X <- T, X =< Pivot])
	++ [Pivot] ++
	qsort([X || X <- T, X > Pivot]).

Short + Clean + Elegant = Beautiful.

Erlang and Poker

Just when I started writing some poker odds analysis code in Erlang, a friend sent me this link. Sometimes it looks like the Universe really wants you to do something, isn’t it? :)

Learning Erlang, day 1: No Variables?

I first heard of Erlang from SamePlace creator, Massimiliano Mirra. He mostly praised the functional nature of the language and its performance.

I always listen to my friends, so I made a mental note, and every once in a while I tried to start with Erlang, but other stuff(tm) always got the priority.

A few days ago, generating a burst of blog posts, the Pragmatic Programmers released the beta version of Programming Erlang. This was not a coincidence. When both Massimiliano and the Pragmatic Programmers suggest you should learn a new language you better do it, and be happy :)

So I went to the pragprog website and looked through the table of contents. It was really interesting and I bought the beta book.

Yesterday I got my hands wet with erlangness for the first time and decided to create a new category of posts, Learning Erlang, that will be filled with my observation about my efforts to learn a functional language after all these years of object orientedness.

The first thing you will notice when working with erlang is that there are no variables. Ok, stop, don’t close the browser, it’s not entirely true, there are variables, but you can assign them only once.

To better explain how erlang treats variables I’ll show you a snippet taken from the erlang interactive interpreter, erl:

Eshell V5.5.3  (abort with ^G)
1> X = 45.
45
2> X.
45
3> X = 23.
	

=ERROR REPORT==== 15-Mar-2007::09:55:53 ===
Error in process <0.29.0> with exit value: {{badmatch,23},[{erl_eval,expr,3}]}

  • exited: {{badmatch,23},[{erl_eval,expr,3}]} ** 4> X = 45. 45

Line 1 just assigns the X variable (in erlang variables start with a capital letter, and statements end with a period). What erlang really does here is matching X with 45. It notices that X is unbound and does whatever it can to make the statement true, so it binds X to 45. In line 2 we just check what X is bound to. In line 3 we learn how erlang works by trying to match X (now 45) to 23. Boom! nasty error for us. Being very scared, in line 4 we try to match X to 45, just in case, and we notice erlang likes that statement.

I promise that once you get used to this way of handling variables it doesn’t look so strange anymore :)