RabbitFarm

2022-05-01

The Weekly Challenge 162

The examples used here are from The Weekly Challenge problem statement and demonstrate the working solution.

Part 1

Write a script to generate the check digit of a given ISBN-13 code.

Solution


use strict;
use warnings;

sub isbn_check_digit{
    my($isbn) = @_;
    my $i = 0;
    my @weights = (1, 3);
    my $check_sum = 0;
    my $check_digit;
    map {$check_sum += $_ * $weights[$i]; $i = $i == 0 ? 1 : 0} split(//, $isbn);
    $check_digit = $check_sum % 10;
    return 10 - $check_digit;
}

MAIN:{
    print isbn_check_digit(978030640615) . "\n";
}

Sample Run


$ perl perl/ch-1.pl
7   

References

Challenge 162

posted at: 14:34 by: Adam Russell | path: /perl | permanent link to this entry

The Weekly Challenge 162 (Prolog Solutions)

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1

Write a script to generate the check digit of a given ISBN-13 code.

Solution


weight(-1, 1).
weight(1, 3).

check_sum([], _, 0).
check_sum([H|T], I, CheckSum):-
    N is I * -1,
    check_sum(T, N, C),
    weight(I, Weight),
    CheckSum is H * Weight + C.
isbn_check_digit(ISBN, CheckDigit):-
    check_sum(ISBN, -1, CheckSum),
    Check is mod(CheckSum, 10),
    CheckDigit is 10 - Check.

Sample Run


$ gprolog --consult-file prolog/ch-1.p 
| ?- isbn_check_digit([9, 7, 8, 0, 3, 0, 6, 4, 0, 6, 1, 5], CheckDigit).

CheckDigit = 7

(1 ms) yes

$ gprolog --consult-file prolog/ch-1.p 
| ?- isbn_check_digit([9, 7, 8, 0, 3, 0, 6, 4, 0, 6, 1, 5], 3).    

(1 ms) no

$ gprolog --consult-file prolog/ch-1.p 
| ?- isbn_check_digit([9, 7, 8, 0, 3, 0, 6, 4, 0, 6, 1, 5], 7).         

yes

Notes

Sometimes when writing this sort of code I feel the urge to really unleash the power of Prolog and make the most general solution. What would that mean here though? Generate ISBNs for which a given check digit would be valid? While possible it seems like a kind of weird thing to do. Is it interesting to reason about ISBNs in this way? I seem to think that is unlikely.

This code does what seems to reasonable: generate a check digit given an ISBN, or, given both an ISBN and a check digit confirm that the given check digit is the correct one.

References

Challenge 162

posted at: 14:34 by: Adam Russell | path: /prolog | permanent link to this entry