I’ve been doing the Perl Weekly
Challenges. The
latest
was about calculating the survivor of a stabbing game, and determining
palindromic dates.
For the survivor challenge, the main thought was in working out
an appropriate data structure; it turned out that filling a list with
ID numbers, then splicing it as they're removed, worked best.
my @list=(1..50);
my $n=0;
while (scalar @list > 1) {
$n++;
if ($n>$#list) {
$n=0;
}
splice @list,$n,1;
}
print $list[0],"\n";
Perl6 is the same apart from minor changes in syntax. (With the same
off-by-one error.)
For palindromic dates, I started off doing it the obvious way, using
actual date formatting functions.
my $format='%m%d%Y';
foreach my $d (10957..376199) {
my $u=strftime($format,gmtime($d*86400));
if ((scalar reverse $u) eq $u) {
print "$u\n";
}
}
This lets me trivially change the format being used to search for
other types of palindromic date. However, Perl6 doesn't have strftime,
so I built nested loops, with a checker to skip over non-existent days
at the ends of months.
for 2000..2999 -> $y {
for 1..12 -> $m {
for 1..31 -> $d {
if ($d==31 && ($m==4 || $m==6 || $m==9 || $m==11)) {
next;
} elsif ($m==2 && $d==30) {
next;
} elsif ($m==2 && $d==29 && ($y % 4 != 0 || ($y % 100 == 0 && $y % 400 != 0))) {
next;
}
my $u=sprintf('%02d%02d%04d',$m,$d,$y);
if ($u eq $u.flip) {
say $u;
}
}
}
}
Which is fine and gets the job done, but where my Perl5 version above
runs in about 6.4 seconds, this takes 109 on the same machine. That
seems odd. Surely there's nothing particularly complicated going on
here? In order to test it, I reimplemented this nested-loop algorithm
in Perl5… where it runs in 0.2 seconds (so presumably there's a fair
old overhead on the strftime calls in the original).
This is the first time I've seen Perl6 being this dog-slow at
something. The sprintf maybe?
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.