RosettaCodeData/Task/Lychrel-numbers/Perl/lychrel-numbers.pl
2023-07-01 13:44:08 -04:00

52 lines
1.4 KiB
Perl

use strict;
use warnings;
use English;
use Const::Fast;
use Math::AnyNum qw(:overload);
const my $n_max => 10_000;
const my $iter_cutoff => 500;
my(@seq_dump, @seed_lychrels, @related_lychrels);
for (my $n=1; $n<=$n_max; $n++) {
my @seq = lychrel_sequence($n);
if ($iter_cutoff == scalar @seq) {
if (has_overlap(\@seq, \@seq_dump)) { push @related_lychrels, $n }
else { push @seed_lychrels, $n }
@seq_dump = set_union(\@seq_dump, \@seq);
}
}
printf "%45s %s\n", "Number of seed Lychrels <= $n_max:", scalar @seed_lychrels;
printf "%45s %s\n", "Seed Lychrels <= $n_max:", join ', ', @seed_lychrels;
printf "%45s %s\n", "Number of related Lychrels <= $n_max:", scalar @related_lychrels;
printf "%45s %s\n", "Palindromes among seed and related <= $n_max:",
join ', ', sort {$a <=> $b} grep { is_palindrome($ARG) } @seed_lychrels, @related_lychrels;
sub lychrel_sequence {
my $n = shift;
my @seq;
for (1 .. $iter_cutoff) {
return if is_palindrome($n = next_n($n));
push @seq, $n;
}
@seq;
}
sub next_n { my $n = shift; $n + reverse($n) }
sub is_palindrome { my $n = shift; $n eq reverse($n) }
sub has_overlap {
my ($a, $b) = @ARG;
my %h;
$h{$_}++ for @{$a};
exists $h{$_} and return 1 for @{$b};
0;
}
sub set_union {
my ($a, $b) = @ARG;
my %h;
$h{$_}++ for @{$a}, @{$b};
keys %h;
}