Skip to content

Instantly share code, notes, and snippets.

@mudge
Last active March 17, 2016 08:56
Show Gist options
  • Save mudge/95fb2c66e9127e7de811 to your computer and use it in GitHub Desktop.
Save mudge/95fb2c66e9127e7de811 to your computer and use it in GitHub Desktop.
A Sentient program to convert & complete ISBNs with both 10 & 13 digits (with thanks to @tuzz)
/*
* See the bottom of this file for the specs which show how this definition of
* 10 and 13 digit ISBNs allows us to:
*
* - Convert ISBN-10 to ISBN-13
* - Convert ISBN-13 to ISBN-10
* - Automatically fill in missing digits from ISBN-13
* - Automatically fill in missing digits from ISBN-10
*
* Note that as Sentient does not have characters, an 'X' in an ISBN-10 is
* represented with the number 10.
*/
'use strict';
var Sentient = require('../../lib/sentient');
describe('ISBN', function () {
var machineCode = Sentient.compile({
instructions: [
{ type: 'integer', symbol: 'ten0', width: 5 },
{ type: 'integer', symbol: 'ten1', width: 5 },
{ type: 'integer', symbol: 'ten2', width: 5 },
{ type: 'integer', symbol: 'ten3', width: 5 },
{ type: 'integer', symbol: 'ten4', width: 5 },
{ type: 'integer', symbol: 'ten5', width: 5 },
{ type: 'integer', symbol: 'ten6', width: 5 },
{ type: 'integer', symbol: 'ten7', width: 5 },
{ type: 'integer', symbol: 'ten8', width: 5 },
{ type: 'integer', symbol: 'tenCheckDigit', width: 5 },
{ type: 'integer', symbol: 'thirteenCheckDigit', width: 5 },
{ type: 'push', symbol: 'ten0' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten0' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten1' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten1' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten2' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten2' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten3' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten3' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten4' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten4' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten5' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten5' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten6' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten6' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten7' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten7' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten8' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten8' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'tenCheckDigit' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'tenCheckDigit' },
{ type: 'constant', value: 10 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'thirteenCheckDigit' },
{ type: 'constant', value: 0 },
{ type: 'greaterequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'thirteenCheckDigit' },
{ type: 'constant', value: 9 },
{ type: 'lessequal' },
{ type: 'invariant' },
{ type: 'push', symbol: 'ten0' },
{ type: 'push', symbol: 'ten1' },
{ type: 'push', symbol: 'ten2' },
{ type: 'push', symbol: 'ten3' },
{ type: 'push', symbol: 'ten4' },
{ type: 'push', symbol: 'ten5' },
{ type: 'push', symbol: 'ten6' },
{ type: 'push', symbol: 'ten7' },
{ type: 'push', symbol: 'ten8' },
{ type: 'push', symbol: 'tenCheckDigit' },
{ type: 'collect', width: 10 },
{ type: 'pop', symbol: 'tenDigit' },
// ISBN-10 check digit
{ type: 'push', symbol: 'ten0' },
{ type: 'push', symbol: 'ten1' },
{ type: 'constant', value: 2 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'push', symbol: 'ten2' },
{ type: 'constant', value: 3 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'push', symbol: 'ten3' },
{ type: 'constant', value: 4 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'push', symbol: 'ten4' },
{ type: 'constant', value: 5 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'push', symbol: 'ten5' },
{ type: 'constant', value: 6 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'push', symbol: 'ten6' },
{ type: 'constant', value: 7 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'push', symbol: 'ten7' },
{ type: 'constant', value: 8 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'push', symbol: 'ten8' },
{ type: 'constant', value: 9 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'push', symbol: 'tenCheckDigit' },
{ type: 'constant', value: 10 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'constant', value: 11 },
{ type: 'modulo' },
{ type: 'constant', value: 0 },
{ type: 'equal' },
{ type: 'invariant' },
// ISBN-13 check digit
{ type: 'constant', value: 9 },
{ type: 'constant', value: 8 },
{ type: 'add' },
{ type: 'push', symbol: 'ten1' },
{ type: 'add' },
{ type: 'push', symbol: 'ten3' },
{ type: 'add' },
{ type: 'push', symbol: 'ten5' },
{ type: 'add' },
{ type: 'push', symbol: 'ten7' },
{ type: 'add' },
{ type: 'push', symbol: 'thirteenCheckDigit' },
{ type: 'add' },
{ type: 'constant', value: 7 },
{ type: 'push', symbol: 'ten0' },
{ type: 'add' },
{ type: 'push', symbol: 'ten2' },
{ type: 'add' },
{ type: 'push', symbol: 'ten4' },
{ type: 'add' },
{ type: 'push', symbol: 'ten6' },
{ type: 'add' },
{ type: 'push', symbol: 'ten8' },
{ type: 'add' },
{ type: 'constant', value: 3 },
{ type: 'multiply' },
{ type: 'add' },
{ type: 'constant', value: 10 },
{ type: 'modulo' },
{ type: 'constant', value: 0 },
{ type: 'equal' },
{ type: 'invariant' },
{ type: 'constant', value: 9 },
{ type: 'constant', value: 7 },
{ type: 'constant', value: 8 },
{ type: 'push', symbol: 'ten0' },
{ type: 'push', symbol: 'ten1' },
{ type: 'push', symbol: 'ten2' },
{ type: 'push', symbol: 'ten3' },
{ type: 'push', symbol: 'ten4' },
{ type: 'push', symbol: 'ten5' },
{ type: 'push', symbol: 'ten6' },
{ type: 'push', symbol: 'ten7' },
{ type: 'push', symbol: 'ten8' },
{ type: 'push', symbol: 'thirteenCheckDigit' },
{ type: 'collect', width: 13 },
{ type: 'pop', symbol: 'thirteenDigit' },
{ type: 'variable', symbol: 'thirteenDigit' },
{ type: 'variable', symbol: 'tenDigit' }
]
});
it('can convert 10-digit ISBNs to 13 digits', function () {
var result = Sentient.run(machineCode, { tenDigit: [3, 3, 1, 9, 2, 1, 7, 2, 8, 3] });
expect(result.thirteenDigit).toEqual([9, 7, 8, 3, 3, 1, 9, 2, 1, 7, 2, 8, 4]);
});
it('can convert 13-digit ISBNs to 10 digits', function () {
var result = Sentient.run(machineCode, { thirteenDigit: [9, 7, 8, 3, 3, 1, 9, 2, 1, 7, 2, 8, 4] });
expect(result.tenDigit).toEqual([3, 3, 1, 9, 2, 1, 7, 2, 8, 3]);
});
it('can complete incomplete 13-digit ISBNs', function () {
var result = Sentient.run(machineCode, { thirteenDigit: [9, 7, 8, 3, 3, undefined, 9, 2, 1, 7, 2, 8, 4] });
expect(result.thirteenDigit).toEqual([9, 7, 8, 3, 3, 1, 9, 2, 1, 7, 2, 8, 4]);
});
it('can convert incomplete 13-digit ISBNs to 10 digits', function () {
var result = Sentient.run(machineCode, { thirteenDigit: [9, 7, 8, 3, 3, undefined, 9, 2, 1, 7, 2, 8, 4] });
expect(result.tenDigit).toEqual([3, 3, 1, 9, 2, 1, 7, 2, 8, 3]);
});
it('can complete incomplete 10-digit ISBNs', function () {
var result = Sentient.run(machineCode, { tenDigit: [3, 3, undefined, 9, 2, 1, 7, 2, 8, 3] });
expect(result.tenDigit).toEqual([3, 3, 1, 9, 2, 1, 7, 2, 8, 3]);
});
it('can convert incomplete 10-digit ISBNs to 13 digits', function () {
var result = Sentient.run(machineCode, { tenDigit: [3, 3, undefined, 9, 2, 1, 7, 2, 8, 3] });
expect(result.thirteenDigit).toEqual([9, 7, 8, 3, 3, 1, 9, 2, 1, 7, 2, 8, 4]);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment