exercism-perl5

Repository for my Perl 5 Exercism exercises
git clone git://git.samirparikh.com/exercism-perl5
Log | Files | Refs | README

Luhn.pm (1387B) - raw


      1 package Luhn;
      2 
      3 use strict;
      4 use warnings;
      5 use feature qw<say>;
      6 
      7 use Exporter qw<import>;
      8 our @EXPORT_OK = qw<is_luhn_valid>;
      9 
     10 use List::Util qw(sum);
     11 
     12 sub step1 {
     13     my ( $digit ) = @_;
     14     if ( $digit * 2 > 9 ) {
     15         return $digit * 2 - 9;
     16     } else {
     17         return $digit * 2;
     18     }
     19 }
     20 
     21 sub is_luhn_valid {
     22     my ($input) = @_;
     23 
     24     # remove whitespace
     25     $input =~ s/\s+//g;
     26 
     27     # return false if string is less than 2 digits
     28     return 0 if ( length $input < 2 );
     29 
     30     # return false if we find a non-decimal character
     31     return 0 if ( $input =~ m/\D/ );
     32 
     33     # split input into array
     34     my @numbers = ( $input =~ m/\d/g );
     35 
     36     # the special variable $#numbers represents the index of the last element
     37     # of the array @numbers
     38 
     39     if ( $#numbers % 2 ) { # even number of digits, e.g. 1234
     40         for ( my $i = 0; $i < $#numbers; $i += 2 ) {
     41             $numbers[$i] = step1( $numbers[$i] );
     42         }
     43     } else { # odd number of digits, e.g. 123
     44         for ( my $i = 1; $i < $#numbers; $i += 2 ) {
     45             $numbers[$i] = step1( $numbers[$i] );
     46         }
     47     }
     48 
     49     # fancy way of saying that if the sum of the numbers in the array is NOT
     50     # divisible by zero (in which case `sum( @numbers ) % 10` returns a non
     51     # zero number which evaluates to true) we return false (0).  Otherwise,
     52     # return true (1).
     53     return sum( @numbers ) % 10 ? 0 : 1;
     54 
     55 }
     56 
     57 1;