RabbitFarm

2022-05-15

Happily Computing Prime Palindrome Numbers

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1

Write a script to find all prime numbers less than 1000, which are also palindromes in base 10.

Solution


use strict;
use warnings;
use Math::Primality qw/is_prime/;

sub palindrome_primes_under{
    my($n) = shift;
    my @palindrome_primes;
    {
        $n--;
        unshift @palindrome_primes, $n if(is_prime($n) && join("", reverse(split(//, $n))) == $n);
        redo if $n > 1;  
    }
    return @palindrome_primes;
}

MAIN:{
    print join(", ", palindrome_primes_under(1000));
}

Sample Run


$ perl perl/ch-1.pl
2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383, 727, 757, 787, 797, 919, 929

Notes

I have become incorrigible in my use of redo! The novelty just hasn't worn off I suppose. There is nothing really wrong with it, of course, it's just not particularly modern convention what with it's vaguely goto like behavior. Anyway, there's not a whole lot to cover here. All the real work is done in the one line which tests both primality and, uh, palindromedary.

Part 2

Write a script to find the first 8 Happy Numbers in base 10.

Solution


use strict;
use warnings;
use boolean;
use constant N => 8;

sub happy{
    my $n = shift;
    my @seen;
    my $pdi = sub{
        my $n = shift;
        my $total = 0;
        {
            $total += ($n % 10)**2;
            $n = int($n / 10);
            redo if $n > 0;
        }
        return $total;
    };
    {
        push @seen, $n;
        $n = $pdi->($n);
        redo if $n > 1 && (grep {$_ == $n} @seen) == 0; 
    }
    return boolean($n == 1);
}

MAIN:{
    my $i = 0;
    my @happy;
    {
        $i++;
        push @happy, $i if happy($i);
        redo if @happy < N;
    }
    print join(", ", @happy) . "\n";
}

Sample Run


$ perl perl/ch-2.pl
1, 7, 10, 13, 19, 23, 28, 31

Notes

This solution has even more redo, huzzah! Again, fairly straightforward bit of code which follows the definitions. The happiness check is done using a perfect digit invariant (PDI) function, here rendered as an anonymous inner subroutine. A good chance here when looking at this code to remind ourselves that $n inside that anonymous subroutine is in a different scope and does not effect the outer $n!

References

Challenge 164

posted at: 23:58 by: Adam Russell | path: /perl | permanent link to this entry