package Palindrome; use strict; use warnings; use List::Util qw(min max); sub new { my ( $class, $min_max ) = @_; # check whether min_factor key exists; if not, set to 1 $min_max->{min_factor} = 1 unless ( exists $min_max->{min_factor} ); # %factors is a hash whose values are array references containting # factor pairs for the products (which are represented by the keys) my %factors; foreach my $x ( $min_max->{min_factor} .. $min_max->{max_factor} ) { foreach my $y ( $x .. $min_max->{max_factor} ) { my $product = $x * $y; # add factor pair if product is a palindrome push @{$factors{$product}} => [$x, $y] if (_is_palindrome($product)); } } # return an object that represents all palindrome products and their factors bless \%factors, $class } sub largest { my $self = shift; my $largest_product = max keys %{ $self }; # hash keys are not sorted return ( { value => $largest_product, factors => $self->{ $largest_product }, } ); } sub smallest { my $self = shift; my $smallest_product = min keys %{ $self }; # hash keys are not sorted return ( { value => $smallest_product, factors => $self->{ $smallest_product }, } ); } sub _init { my ( $self, $arg ) = @_; $self->{min_factor} = defined $arg->{min_factor} ? $arg->{min_factor} : 1; $self->{max_factor} = $arg->{max_factor}; } sub _is_palindrome { return $_[0] eq reverse $_[0]; } 1;