commit 235cd60653aa9e8088ea381afcabfc6703d1ceaf
parent e35bd4e67fe0806a2df1de17c73e968070fc6897
Author: Samir Parikh <noreply@samirparikh.com>
Date: Fri, 26 Aug 2022 22:29:44 +0000
get all tests to pass
Diffstat:
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/luhn/Luhn.pm b/luhn/Luhn.pm
@@ -7,24 +7,51 @@ use feature qw<say>;
use Exporter qw<import>;
our @EXPORT_OK = qw<is_luhn_valid>;
+use List::Util qw(sum);
+
+sub step1 {
+ my ( $digit ) = @_;
+ if ( $digit * 2 > 9 ) {
+ return $digit * 2 - 9;
+ } else {
+ return $digit * 2;
+ }
+}
+
sub is_luhn_valid {
my ($input) = @_;
- #print "input was originally '$input'\n";
- $input =~ s/\s+//g; # remove whitespace
- #print "input = $input\n";
+
+ # remove whitespace
+ $input =~ s/\s+//g;
# return false if string is less than 2 digits
return 0 if ( length $input < 2 );
# return false if we find a non-decimal character
return 0 if ( $input =~ m/\D/ );
- my @numbers = ( $input =~ m/\d/g ); # split out input into array
- print join( ":", @numbers), "\n";
+
+ # split input into array
+ my @numbers = ( $input =~ m/\d/g );
# the special variable $#numbers represents the index of the last element
# of the array @numbers
- return undef;
+ if ( $#numbers % 2 ) { # even number of digits, e.g. 1234
+ for ( my $i = 0; $i < $#numbers; $i += 2 ) {
+ $numbers[$i] = step1( $numbers[$i] );
+ }
+ } else { # odd number of digits, e.g. 123
+ for ( my $i = 1; $i < $#numbers; $i += 2 ) {
+ $numbers[$i] = step1( $numbers[$i] );
+ }
+ }
+
+ # fancy way of saying that if the sum of the numbers in the array is NOT
+ # divisible by zero (in which case `sum( @numbers ) % 10` returns a non
+ # zero number which evaluates to true) we return false (0). Otherwise,
+ # return true (1).
+ return sum( @numbers ) % 10 ? 0 : 1;
+
}
1;