in reply to Summing the odd/even digits of a larger number (for upc check digits)...a better way?

Using the autoflush buffer variable trick and the trinary operator along with modifiers and replacing the while loop by using % gives:

use warnings; use strict; print checkUPC('064200115896'); sub checkUPC { # grab and immediately split upc into array, 1 char per element my @chars = split //, shift; return "should be 12 digits in length" if @chars != 12; local $| = 0; my $sum = 0; # loop through to sum even and adjusted odd chars $sum += $chars[$_] * (--$| ? 3 : 1) foreach 0..10; # calculate correct check digit my $check = (10 - $sum % 10) % 10; # return error message if wrong check digit was initially given return $check != $chars[11] ? "invalid checkdigit...should be $che +ck" : 'Ok'; }

Prints:

Ok

Note that this version returns Ok on success. Replace 'Ok' with undef for original behaviour.


DWIM is Perl's answer to Gödel
  • Comment on Re: Summing the odd/even digits of a larger number (for upc check digits)...a better way?
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Summing the odd/even digits of a larger number (for upc check digits)...a better way?
by ikegami (Patriarch) on Jun 22, 2006 at 23:54 UTC

    Why use a special variable in an unintended and undocumented manner when you can use ($t^=1)?

    Change
    local $| = 0; $sum += $chars[$_] * (--$| ? 3 : 1) foreach 0..10;
    to:
    my $t = 0; $sum += $chars[$_] * (($t^=1) ? 3 : 1) foreach 0..10;

    Update: sgifford improved this to:
    my $t = 1; $sum += $chars[$_] * ($t^=2) foreach 0..10;

    Update:
    my $check = (10 - $sum % 10) % 10;
    simplifies to
    my $check = -$sum % 10;