Last active
March 17, 2016 08:56
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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