Finding palindromic numbers most efficiently After reading why is my project euler #4 program not working?, I was contemplating the most efficient way to approach this (finding the target palindrome as early as possible).

Is this snippet about as efficient as it gets?  I am only considering the merits of the logic, not the choice of language.  It would be easier (but not as efficient) to brute-force it with two nested loops.

Also, is this logic common enough for it to have a name?

#!/usr/bin/perl
use strict;
$^W = 1;
$\ = "\n";

my ($n) = @ARGV;
$n = 3 if (! defined $n || $n &lt; 2 || $n &gt; 8);
my ($lo,$hi,$lm);
$lo = substr('10000000000',0,$n);
$hi = substr('99999999999',0,$n);
$lm = substr('100000000000000000000',0,$n*2);

my ($a,$b,$x) = ($hi,$hi);
for (;;) {
    $x = $a*$b;
    if ($x eq reverse $x) {
        print "$x is $a * $b" if ($x &gt; $lm);
        last if ($n &gt; 3); # show them all for small numbers
    }
    next if (!(--$a &lt; $lo) &amp; !(++$b &gt; $hi)); # no short-cut operator here
    ++$a; --$b;
    print "  edge $a $b" if ($n &lt; 3); # show edge for small numbers
    $a += $b; $b = int --$a/2; $a -= $b;
    last if ($a*$b &lt; $lm);
}
Here, you first check if $x is palindrome, but then you will only print it if $x &gt; $lm:


if ($x eq reverse $x) {
    print "$x is $a * $b" if ($x &gt; $lm);
    last if ($n &gt; 3); # show them all for small numbers
}



It would be more efficient to do the other way around, checking $x &gt; $lm first:

if ($x &gt; $lm) {
    if ($x eq reverse $x) {
        print "$x is $a * $b";
        last if ($n &gt; 3); # show them all for small numbers
    }
}


With \$n = 3\$, this makes a big difference: it saves reversing $x 23602 times.

I also tried rewriting the reverse operation,
somewhat inspired by the the duck's comment:
instead of comparing an entire string with its reverse,
it should be more efficient to compare its first half with the reverse of its second half:

sub is_palindrome {
    my ($word) = (@_);
    my $l = length($word);
    foreach my $i (0 .. $l / 2) {
        if (substr($word, $i, 1) ne substr($word, $l - $i - 1, 1)) {
            return;
        }
    }
    return 1;
}


Although this function does only half of the comparisons as in $x eq reverse $x,
at least as interpreted code, this cannot compete with the speed of the compiled reverse function. Using this function the script runs much slower, unfortunately.