Skip to content

Commit 383decd

Browse files
authored
Add isbn-verifier (#350)
* Add `isbn-verifier` * Fix unskipped tests
1 parent 9eb17c8 commit 383decd

File tree

7 files changed

+217
-0
lines changed

7 files changed

+217
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,14 @@
235235
"prerequisites": [],
236236
"difficulty": 2
237237
},
238+
{
239+
"slug": "isbn-verifier",
240+
"name": "ISBN Verifier",
241+
"uuid": "e33144e1-5e77-47b4-9aed-e743b7573ad8",
242+
"practices": [],
243+
"prerequisites": [],
244+
"difficulty": 2
245+
},
238246
{
239247
"slug": "isogram",
240248
"name": "Isogram",
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Instructions
2+
3+
The [ISBN-10 verification process][isbn-verification] is used to validate book identification numbers.
4+
These normally contain dashes and look like: `3-598-21508-8`
5+
6+
## ISBN
7+
8+
The ISBN-10 format is 9 digits (0 to 9) plus one check character (either a digit or an X only).
9+
In the case the check character is an X, this represents the value '10'.
10+
These may be communicated with or without hyphens, and can be checked for their validity by the following formula:
11+
12+
```text
13+
(d₁ * 10 + d₂ * 9 + d₃ * 8 + d₄ * 7 + d₅ * 6 + d₆ * 5 + d₇ * 4 + d₈ * 3 + d₉ * 2 + d₁₀ * 1) mod 11 == 0
14+
```
15+
16+
If the result is 0, then it is a valid ISBN-10, otherwise it is invalid.
17+
18+
## Example
19+
20+
Let's take the ISBN-10 `3-598-21508-8`.
21+
We plug it in to the formula, and get:
22+
23+
```text
24+
(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 == 0
25+
```
26+
27+
Since the result is 0, this proves that our ISBN is valid.
28+
29+
## Task
30+
31+
Given a string the program should check if the provided string is a valid ISBN-10.
32+
Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN.
33+
34+
The program should be able to verify ISBN-10 both with and without separating dashes.
35+
36+
## Caveats
37+
38+
Converting from strings to numbers can be tricky in certain languages.
39+
Now, it's even trickier since the check digit of an ISBN-10 may be 'X' (representing '10').
40+
For instance `3-598-21507-X` is a valid ISBN-10.
41+
42+
[isbn-verification]: https://en.wikipedia.org/wiki/International_Standard_Book_Number
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"BNAndras"
4+
],
5+
"files": {
6+
"solution": [
7+
"isbn-verifier.coffee"
8+
],
9+
"test": [
10+
"isbn-verifier.spec.coffee"
11+
],
12+
"example": [
13+
".meta/example.coffee"
14+
]
15+
},
16+
"blurb": "Check if a given string is a valid ISBN-10 number.",
17+
"source": "Converting a string into a number and some basic processing utilizing a relatable real world example.",
18+
"source_url": "https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation"
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class IsbnVerifier
2+
@isValid: (isbn) ->
3+
digits = isbn.replace /-/g, ''
4+
return false if digits.length != 10
5+
6+
sum = 0
7+
for i in [0..9]
8+
digit = digits[i]
9+
if digit == 'X'
10+
return false if i != 9
11+
digit = 10
12+
return false if /\D/.test digit
13+
14+
sum += digit * (10 - i)
15+
sum % 11 == 0
16+
17+
module.exports = IsbnVerifier
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[0caa3eac-d2e3-4c29-8df8-b188bc8c9292]
13+
description = "valid isbn"
14+
15+
[19f76b53-7c24-45f8-87b8-4604d0ccd248]
16+
description = "invalid isbn check digit"
17+
18+
[4164bfee-fb0a-4a1c-9f70-64c6a1903dcd]
19+
description = "valid isbn with a check digit of 10"
20+
21+
[3ed50db1-8982-4423-a993-93174a20825c]
22+
description = "check digit is a character other than X"
23+
24+
[9416f4a5-fe01-4b61-a07b-eb75892ef562]
25+
description = "invalid check digit in isbn is not treated as zero"
26+
27+
[c19ba0c4-014f-4dc3-a63f-ff9aefc9b5ec]
28+
description = "invalid character in isbn is not treated as zero"
29+
30+
[28025280-2c39-4092-9719-f3234b89c627]
31+
description = "X is only valid as a check digit"
32+
33+
[f6294e61-7e79-46b3-977b-f48789a4945b]
34+
description = "valid isbn without separating dashes"
35+
36+
[185ab99b-3a1b-45f3-aeec-b80d80b07f0b]
37+
description = "isbn without separating dashes and X as check digit"
38+
39+
[7725a837-ec8e-4528-a92a-d981dd8cf3e2]
40+
description = "isbn without check digit and dashes"
41+
42+
[47e4dfba-9c20-46ed-9958-4d3190630bdf]
43+
description = "too long isbn and no dashes"
44+
45+
[737f4e91-cbba-4175-95bf-ae630b41fb60]
46+
description = "too short isbn"
47+
48+
[5458a128-a9b6-4ff8-8afb-674e74567cef]
49+
description = "isbn without check digit"
50+
51+
[70b6ad83-d0a2-4ca7-a4d5-a9ab731800f7]
52+
description = "check digit of X should not be used for 0"
53+
54+
[94610459-55ab-4c35-9b93-ff6ea1a8e562]
55+
description = "empty isbn"
56+
57+
[7bff28d4-d770-48cc-80d6-b20b3a0fb46c]
58+
description = "input is 9 characters"
59+
60+
[ed6e8d1b-382c-4081-8326-8b772c581fec]
61+
description = "invalid characters are not ignored after checking length"
62+
63+
[daad3e58-ce00-4395-8a8e-e3eded1cdc86]
64+
description = "invalid characters are not ignored before checking length"
65+
66+
[fb5e48d8-7c03-4bfb-a088-b101df16fdc3]
67+
description = "input is too long but contains a valid isbn"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class IsbnVerifier
2+
@isValid: (isbn) ->
3+
4+
module.exports = IsbnVerifier
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
IsbnVerifier = require './isbn-verifier'
3+
4+
describe 'ISBN Verifier', ->
5+
it 'valid ISBN', ->
6+
expect(IsbnVerifier.isValid '3-598-21508-8').toEqual true
7+
8+
xit 'invalid ISBN check digit', ->
9+
expect(IsbnVerifier.isValid '3-598-21508-9').toEqual false
10+
11+
xit 'valid ISBN with a check digit of 10', ->
12+
expect(IsbnVerifier.isValid '3-598-21507-X').toEqual true
13+
14+
xit 'check digit is a character other than X', ->
15+
expect(IsbnVerifier.isValid '3-598-21507-A').toEqual false
16+
17+
xit 'invalid check digit in ISBN is not treated as zero', ->
18+
expect(IsbnVerifier.isValid '4-598-21507-B').toEqual false
19+
20+
xit 'invalid character in ISBN is not treated as zero', ->
21+
expect(IsbnVerifier.isValid '3-598-P1581-X').toEqual false
22+
23+
xit 'X is only valid as a check digit', ->
24+
expect(IsbnVerifier.isValid '3-598-2X507-9').toEqual false
25+
26+
xit 'valid ISBN without separating dashes', ->
27+
expect(IsbnVerifier.isValid '3598215088').toEqual true
28+
29+
xit 'ISBN without separating dashes and X as check digit', ->
30+
expect(IsbnVerifier.isValid '359821507X').toEqual true
31+
32+
xit 'ISBN without check digit and dashes', ->
33+
expect(IsbnVerifier.isValid '359821507').toEqual false
34+
35+
xit 'too long ISBN and no dashes', ->
36+
expect(IsbnVerifier.isValid '3598215078X').toEqual false
37+
38+
xit 'too short ISBN', ->
39+
expect(IsbnVerifier.isValid '00').toEqual false
40+
41+
xit 'ISBN without check digit', ->
42+
expect(IsbnVerifier.isValid '3-598-21507').toEqual false
43+
44+
xit 'check digit of X should not be used for 0', ->
45+
expect(IsbnVerifier.isValid '3-598-21515-X').toEqual false
46+
47+
xit 'empty ISBN', ->
48+
expect(IsbnVerifier.isValid '').toEqual false
49+
50+
xit 'input is 9 characters', ->
51+
expect(IsbnVerifier.isValid '134456729').toEqual false
52+
53+
xit 'invalid characters are not ignored after checking length', ->
54+
expect(IsbnVerifier.isValid '3132P34035').toEqual false
55+
56+
xit 'invalid characters are not ignored before checking length', ->
57+
expect(IsbnVerifier.isValid '3598P215088').toEqual false
58+
59+
xit 'input is too long but contains a valid ISBN', ->
60+
expect(IsbnVerifier.isValid '98245726788').toEqual false

0 commit comments

Comments
 (0)