Skip to content

Eulergy

November 30, 2009
tags:

It wasn’t my plan to get into all things Euler when I started this thread two posts ago.

However it has been a nice little tangent and doing a Google on Perl+Euler does throw up a number of links (over 100K of them in fact). Its worth following up some of these and playing around with the problem and the published code.

One such link is the blog post Distrust Simplicity: PROJECT EULER, PROBLEM #1. This post shows solutions to Euler problem 1 in Ruby, Python, Common Lisp, Clojure, Haskell and Perl.

Here is the Perl solution provided in said post:

#!/usr/bin/perl
use strict;
use List::Util qw(reduce);

# find the natural numbers less than 1000 divisible by 3 or 5
my @multiples = ();
foreach (1..999) {
    if ($_ % 3 == 0 || $_ % 5 == 0) { push(@multiples, $_); }
}

# sum them
print reduce { $a + $b } @multiples;

This could be simplified with a functional twist like most of the other solutions provided:

use Modern::Perl;
use List::Util qw(sum);

say sum grep { $_ % 3 == 0 || $_ % 5 == 0 } 1..999;

And lets not forget our mandatory autobox variation!

use Modern::Perl;
use autobox::Core;

[1..999]->grep( sub{ $_ % 3 == 0 || $_ % 5 == 0 } )->sum->say;

 
Another link I noticed which may bear fruit in the future is a very new Github repo for Project Euler solutions in Modern Perl.

To quote the Readme:

This module is intended to provide solutions to the Project Euler problems (http://projecteuler.net) using modern perl best practices and object oriented programming. For this reason I will be making heavy use of the Moose module(s) to wrap the solutions into objects.

I wish the author, Lespea (Adam Lesperance), the best of luck with this spanking new project.

I think thats enough Eulergizing from me for a while ;-)

/I3az/

Euler, Euler, Euler, Oi, Oi, Oi!

November 26, 2009
tags:

The Last of the Careless Men blog kindly referred to my Euler blog post from last week.

The blog post brought to my attention the Euler Benchmark Suite. To quote from the Readme:

The Euler Benchmark Suite aims at comparing language speeds for the Euler

So I was curious to see what this version of the Euler 4 in Perl5 looked like.

use strict; use warnings;
 
my $max = 0;
for my $a ( 100..999 ){
    for my $b ( $a..999 ){
        my $product = $a * $b;
 
        $max = $product if $product > $max
                       and $product eq reverse $product;
    }
}
 
print "$max\n";

At first glance this doesn’t look as “elegant” as the functional code I posted last week.

However remember the above code was optimised for speed! It comes it at 3.5 times faster than even this slightly more optimised version of last weeks functional code below, which now comes it at around 0.48s here:

say max 
    grep { $_ eq reverse $_ } 
    map {
        my $x = $_;
        map { $x * $_ } $x .. 1000;
    } 100..1000;

 

Another thing of interest from the blog post was the Perl6 example. Like with Ruby example its definitely easier to grok things going in a chain from left to right, ie. just like how we read english text.

autobox to the rescue!

use autobox::Core;

[1..1000]->map( sub{ my $x = $_; map { $x * $_ } $x..1000 } )->grep( sub{ $_ eq reverse $_ } )->max->say;

Not bad. And comes in at respectabe average of 1.25s. However having that extra map within the map method is not too elegant.

Luckily autobox is extensible! So lets add a Cartesian Product method to autobox:

use autobox::Core;

sub autobox::Core::ARRAY::product {
    my $a = shift;
    my @c = map { [ $_ ] } @$a;
    
    for my $b (@_) {
        @c = map { my $x = $_; map { [ $x, @$_ ] } @c } @$b;   
    }
    
    return \@c;
}

[1..1000]->product( [1..1000] )->map( sub{ $_->[0] * $_->[1] } )->grep( sub{ $_ eq reverse $_ } )->max->say;

Now thats really nice. Now if future versions of Perl can provide a mechanism to allow for blocks (ie. anonymous subs) to passed more seamlessly, say like

[1..1000]->product( [1..1000] )->map(){ $_->[0] * $_->[1] }->grep(){ $_ eq reverse $_ }->max->say;

# or even

[1..1000]->product( [1..1000] )->map{ $_->[0] * $_->[1] }->grep{ $_ eq reverse $_ }->max->say;

Then we’re really cooking!

/I3az/

This post is in memory of Colin. My Father-in-law and a fellow blogger who suddenly and unexpectedly passed away yesterday. RIP

Between thought and expression

November 21, 2009

Comparing computer languages can usually be interesting, sometimes informative, often amusing and in lots of cases just damn annoying!

Still this recent Hacker News post about Python vs Clojure did catch my eye.

Despite the fact the author of the blog post had pulled the Python code from answers to Project Euler the pythonista’s quite correctly cried foul because it wasn’t well written idiomatic python example and so was an unfair comparison.

There’s a lot of code out there posted on those intertubes over the years. However languages and practises evolve but unfortunately intertube posts can remain set in stone! Perl is often weighed down by its past history on the intertubes. One good way forward is just to produce more Modern Perl posts.

Anyway i digress, so moving on lets take a look at the Euler 4 – Finding Palindroms. This was the Clojure example that was put forward in the blog post:

(reduce max
    (filter #(let [s (str %)]
               (= (seq s) (reverse s)))
            (for [x (range 100 1000)
                  y (range 100 1000)]
              (* x y))))

Now in reply to this a much more idiomatic python example was provided:

print max(s for s in (x * y 
    for x in range(111, 1000) 
    for y in range(x, 1000))
    if list(str(s)) == list(reversed(str(s))))

This uses Python’s list comprehension. Definitely a very powerful construct. However i do find i get lost very quickly when trying to follow long nested comprehension’s :(

In this same Python post there is also mention of a twitter post by Yukihiro Matz, the creator of Ruby. Matz provided the following Ruby example:

p [*100..1000].product([*100..1000]).map{|x,y| x*y}.select{|s|s=s.to_s; s==s.reverse}.max

Despite being formatted for twitter (ie. one line) i found it easy to follow through the logic.

Ruby & Python are not the only languages that can produce an elegant solution! So not to be out done here is a Perl example. In fact its the exact same code repeated three times but formatted differently:

use Modern::Perl;
use List::Util q(max);

# twitter one liner
say max grep { $_ eq reverse $_ } map { my $x = $_; map { $x * $_ } 100..1000 } 100..1000;


# again in lispy style format
say 
  max 
    grep { $_ eq reverse $_ } 
      map {
        my $x = $_;
        map { $x * $_ } 100..1000;
      } 100..1000;

# and finally in my preferred more perlish alignment
say max 
    grep { $_ eq reverse $_ } 
    map {
        my $x = $_;
        map { $x * $_ } 100..1000;
    } 100..1000;

The perl code speaks for itself.. its wonderfully clear and succinct. Also its fast, each version runs in under a second on my machine!

/I3az/

RefactorMyCode.com and Perl

November 15, 2009
tags:

Well if you hadn’t heard of Stackoverflow when i mentioned about it last month then chances are you’ve definitely not heard of RefactorMyCode either.

Its yet another interesting and engrossing site which I stumbled across in the past year, funnily enough after hearing about it from an answer to a Stackoverflow question.

The premise of the site is if you have some working code that you’re not totally happy with then offer it up for code review with the hope someone can help refactor it.

The Perl section could do with some more input and engagement. But don’t just stop there because seeing how snippets of code in other languages are refactored is also a good learning experience.

/I3az/

Best things in life come in threes

November 8, 2009

Following on from my last post it seems I have also been waiting for a kind of virtual conjunction between Perl 5.10.1, Parrot 1.0 & Padre being a year old.

Perl 5.10.1

Currently I run 5.8.8 in production on all servers that I manage. I do have Perl 5.10.0 running locally on my Mac but only for playing with.

So first step is to load Perl 5.10.1 on my Mac (Tiger) alongside my other Perl’s and then start testing & with the plan to roll it out to replace 5.8.8 in the not too distant future.

These are my steps to load 5.10.1 locally so that it doesn’t conflict with any other Perl I have here:

  • Download & unpack Perl source code in my normal user login
  • ./Configure -de -Dusethreads -Dprefix=~/local/Perl/perl-5.10.1/
  • gmake
  • gmake test
  • gmake install-all

I now have Perl 5.10.1 running out of my $HOME directory.

This all worked fine except the default location of .cpan directory was in $HOME (~/.cpan). This could clash with other locally installed Perl if nothing is done so I amended everything in cpan shell to use ~/local/Perl/perl-5.10.1/.cpan instead (I did this using “o conf”).

I then quickly blasted my new local Perl 5.10.1 with a few CPAN modules which included:

  • Moose
  • MooseX::Declare
  • autobox::Core
  • DateTime
  • XML::LibXML
  • Devel::REPL

All modules I selected installed without a single hitch. CPAN comes up trumps again!

Devel::REPL was of great interest to me because when I last tried to install this on 5.8.8 & 5.10.0 I did have some problems.

This time it installed & worked wonderfully. Only slight issue was there was no command line history? (ie. readline). This was easily resolved by loading Bundle::CPAN (which also gave cpan shell history as well!)

Padre

Normally I don’t compile Perl with threads. However I needed it for Padre, which is something I forgot about when I last tried installing Padre on my local 5.10.0 :(

I installed the following CPAN modules into my new Perl 5.10.1:

  • Alien::wxWidgets
  • Wx
  • Padre

All compiled & installed seamlessly. On starting Padre I got a nice pretty butterfly splash screen but then unfortunately it crashed :(

As with most things in life if you not starting off with a clean slate then it may cause problems. I had some residue stuff from previous attempt that was part of the problem.

Two things were needed resolve this stumbling block:

  • Remove WxWidget which was installed via MacPorts (sudo port deactivate wxWidgets)
  • Make sure new Perl 5.10.1 was first Perl in $PATH env variable. Because even though I was running 5.10.1 CPAN shell the Wx module seemed fixated on picking up Alien::wxWidgets from the first Perl it could get its hands on :-P

After this reinstalling the Wx & Padre modules gave me a fully functional Padre.

Parrot 1.0 / Rakudo / Perl6

I was now using Padre 0.48 to edit & run my Perl 5.10.1 code. Want I wanted now was to add Perl6 into the mix.

For this I just followed the instructions from Rakudo site and installed it in my local user dir with no hitch at all.

Next in Perl 5.10.1 I installed the Padre::Plugin::Perl6 to make Padre Perl6 aware. My first bit of Perl6 code ran from Padre & command line perfectly (don’t forget to add your rakudo path to $PATH env):

use v6;

for 1..10 { .say }

class Dog {
    method bark { "woof" }
}

my Dog $rover .= new;
my $spot = Dog.new;

say $rover.bark;
say $spot.bark;

 

So where do I stand with Padre? Well I do love my Textmate so it is going to be hard to tug me away from it.

But I love the idea of an editor being hosted and extensible in Perl. So come my next round of free time I may find the tugging from Padre just to strong to resist ;-)

/I3az/

Patience is a virtue

October 31, 2009

For about a year I’ve put off replacing my Apple iMac with a Mac Pro until Snow Leopard arrived.

But thats nothing because I’ve been hanging on to my old, tired and very battered Sony Ericsson mobile phone while I’ve been waiting for the iPhone to eventually come to my mobile phone network

Waiting looks to have paid off because the new 27inch iMac with the Nehalem processors certainly look sweet. I even got to play with magic mouse at an Apple store the other day and have to say first impressions were very nice.

So new iMac will be a nice Xmas pressie :)

The iPhone is a few months off yet but I can hold on a bit longer :(

The temptation to buy a Google Android phone was strong though. It came close especially when Google announced that Perl was available for it.

Gosh having Perl on a “mobile” device brings back memories. I had Perl running on my Psion Revo PDA back in the day.

Unfortunately no Perl on the iPhone thus far… unless its jail broken!

Still perusing the iTunes App Store does show up a few things Perl. O’Reilly have “ported” quite a few of their books to the store.

Amazingly i am still an app virgin on my iPod Touch! So I thought I’d give it a go and purchase Perl Pocket Reference app.

I can’t say its this e-book is going to set my world alight but for £1.79 I couldn’t really go wrong and you will never know when it will come in handy.

/I3az/

Blogging Milestone

October 22, 2009

When I started this blog my “ideal” scenario was to post weekly. However my “pragmatic” operand was to at least post every month.

So with a broad grin of achievement I see that yesterday I passed the milestone of posting a blog entry on every single month for a whole year!

Always nice to give one self a little pat on the back from time to time. But I also have to thank Perl Iron Man for providing the required stimulus at the right moment :)

I’ll try not to rest on my laurels so I will see if I can raise the gears up a few notches over next few months (surely I can become more than a paper man!).

Before I go a couple of recent blogging changes that I can’t take any credit for whatsoever are:

  • WordPress syntax highlighting as changed again. Perl code is now is a more subtle nicer looking font
  • iPhone / iPod Touch users will now see a tailored rendering of this site. Looks very snazzy.

/I3az/

Follow

Get every new post delivered to your Inbox.