# ETOOBUSY ðŸš€ minimal blogging for the impatient

# PWC162 - ISBN-13

**TL;DR**

Here we are with TASK #1 from The Weekly Challenge #162. Enjoy!

# The challenge

Write a script to generate the check digit of given ISBN-13 code. Please refer wikipedia for more information.

Example`ISBN-13 check digit for '978-0-306-40615-7' is 7.`

# The questions

Iâ€™m assuming that no validation of the inputs have to be done, like making sure that there are 12+1 digits, separators are in the right place, etc.

# The solution

Letâ€™s first reshuffle the formula for calculating the goal value:

\[x_{13} = (10 - ((x_1 + 3 x_2 + x_3 + 3 x_4 + ... + x_{11} + 3 x_{12}) \mod{10})) \mod{10} \\ x_{13} = (- (x_1 + 3 x_2 + x_3 + 3 x_4 + ... + x_{11} + 3 x_{12})) \mod{10} \\ x_{13} = (-x_1 - 3 x_2 - x_3 - 3 x_4 + ... - x_{11} - 3 x_{12}) \mod{10} \\ x_{13} = \sum_{i = 1}^{6} (-x_{2i-1} - 3 x_{2i}) \mod{10}\]So we can take pairs of consecutive digits and address them as in the parenthesis in the summation above.

Letâ€™s start Raku:

```
#!/usr/bin/env raku
use v6;
sub MAIN (Str:D $input = '978-0-306-40615-7') {
put "ISBN-13 check digit for '$input' is {isbn_13($input)}.";
}
sub isbn_13 ($input) {
$input.comb(/\d/)[0..11] # focus on first 12 digits
.map({-$^a - 3 * $^b}) # apply equivalent weights
.sum % 10; # sum and take remainder
}
```

Weâ€™re concentrating on the first 12 digits, so the `comb`

gets the
digits and the slice `[0..11]`

takes the first 12 of them. The following
`map`

/`sum`

tandem implements the formula seen above.

Letâ€™s go Perl now, trying to show some *Raku*-ish dialect!

```
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
use List::Util qw< pairmap sum >;
my $input = shift // '978-0-306-40615-7';
say "ISBN-13 check digit for '$input' is @{[isbn_13($input)]}.";
sub isbn_13 ($input) {
sum(
pairmap { -$a - 3* $b }
($input =~ m{(\d)}gmxs)[0 .. 11]
) % 10;
}
```

Function `pairmap`

only appeared in version 1.29 of List::Util, but
we are OK with the constraint on `perl`

â€™s version which appeared three
years later (give or take a couple of months). It allows us to replicate
the *map taking two values at a time* behaviour that comes stock in
Raku, so why not?

The other *rakuism* is in the embedding of the call to `isbn_13`

directly into the string:

```
say "ISBN-13 check digit for '$input' is @{[isbn_13($input)]}.";
# ^^^^^^^^^^^^^^^^^^^^
```

This is hackish in Perl, although it also funnily gets an aura of secret operator (apparently, itâ€™s the Babycart operator).

Stay safe!

*Comments? Octodon, Twitter, GitHub, Reddit, or drop me a line!*