浏览代码

isbn-verifier: implement exercise in Java track (#1004)

* isbn: implement exercise in Java track

* isbn-verifier: Update reference solution.

* isbn-verifier: Add starter implementation.

* Add @FridaTveit 's improvements

* Add some more improvements
Sam Warner 8 年前
父节点
当前提交
9791d82ceb

+ 12
- 0
config.json 查看文件

182
     {
182
     {
183
       "core": false,
183
       "core": false,
184
       "difficulty": 4,
184
       "difficulty": 4,
185
+      "slug": "isbn-verifier",
186
+      "topics": [
187
+        "integers",
188
+        "loops",
189
+        "strings"
190
+      ],
191
+      "unlocked_by": "hamming",
192
+      "uuid": "838bc1d7-b2de-482a-9bfc-c881b4ccb04c"
193
+    },
194
+    {
195
+      "core": false,
196
+      "difficulty": 4,
185
       "slug": "sum-of-multiples",
197
       "slug": "sum-of-multiples",
186
       "topics": [
198
       "topics": [
187
         "arrays",
199
         "arrays",

+ 35
- 0
exercises/isbn-verifier/.meta/src/reference/java/IsbnVerifier.java 查看文件

1
+class IsbnVerifier {
2
+
3
+    boolean isValid(String stringToVerify) {
4
+
5
+        String isbn = stringToVerify.replace("-", "");
6
+        int total = 0;
7
+
8
+        if (isbn.length() != 10) {
9
+            return false;
10
+        }
11
+
12
+        for (int i = 0; i < isbn.length() - 1; i++) {
13
+            char currentChar = isbn.charAt(i);
14
+            if(Character.isDigit(currentChar)) {
15
+                int currentCharVal = Character.getNumericValue(currentChar);
16
+                total += currentCharVal * (10 - i);
17
+            } else {
18
+                return false;
19
+            }
20
+        }
21
+
22
+        char finalChar = isbn.charAt(isbn.length() - 1);
23
+        if (Character.isDigit(finalChar)) {
24
+            total += Character.getNumericValue(finalChar);
25
+        } else if (finalChar == 'X') {
26
+            total += 10;
27
+        } else {
28
+            return false;
29
+        }
30
+
31
+        return total % 11 == 0;
32
+
33
+    }
34
+
35
+}

+ 1
- 0
exercises/isbn-verifier/.meta/version 查看文件

1
+2.0.0

+ 53
- 0
exercises/isbn-verifier/README.md 查看文件

1
+Check if a given ISBN-10 is valid.
2
+
3
+## Functionality
4
+
5
+Given an unknown string the program should check if the provided string is a valid ISBN-10.
6
+Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN.
7
+
8
+The program should allow for ISBN-10 without the separating dashes to be verified as well.
9
+
10
+## ISBN
11
+
12
+Let's take a random ISBN-10 number, say `3-598-21508-8` for this.
13
+The first digit block indicates the group where the ISBN belongs. Groups can consist of shared languages, geographic regions or countries. The leading '3' signals this ISBN is from a german speaking country.
14
+The following number block is to identify the publisher. Since this is a three digit publisher number there is a 5 digit title number for this book.
15
+The last digit in the ISBN is the check digit which is used to detect read errors.
16
+
17
+The first 9 digits in the ISBN have to be between 0 and 9.
18
+The check digit can additionally be an 'X' to allow 10 to be a valid check digit as well.
19
+
20
+A valid ISBN-10 is calculated with this formula `(x1 * 10 + x2 * 9 + x3 * 8 + x4 * 7 + x5 * 6 + x6 * 5 + x7 * 4 + x8 * 3 + x9 * 2 + x10 * 1) mod 11 == 0`
21
+So for our example ISBN this means:
22
+(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 = 0
23
+
24
+Which proves that the ISBN is valid.
25
+
26
+## Caveats
27
+
28
+Converting from string to number can be tricky in certain languages.
29
+It's getting even trickier since the check-digit of an ISBN-10 can be 'X'.
30
+
31
+## Bonus tasks
32
+
33
+* Generate a valid ISBN-13 from the input ISBN-10 (and maybe verify it again with a derived verifier)
34
+
35
+* Generate valid ISBN, maybe even from a given starting ISBN
36
+
37
+# Running the tests
38
+
39
+You can run all the tests for an exercise by entering
40
+
41
+```sh
42
+$ gradle test
43
+```
44
+
45
+in your terminal.
46
+
47
+## Source
48
+
49
+Converting a string into a number and some basic processing utilizing a relatable real world example. [https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation](https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation)
50
+
51
+## Submitting Incomplete Solutions
52
+
53
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.

+ 18
- 0
exercises/isbn-verifier/build.gradle 查看文件

1
+apply plugin: "java"
2
+apply plugin: "eclipse"
3
+apply plugin: "idea"
4
+
5
+repositories {
6
+    mavenCentral()
7
+}
8
+
9
+dependencies {
10
+    testCompile "junit:junit:4.12"
11
+}
12
+
13
+test {
14
+    testLogging {
15
+        exceptionFormat = 'full'
16
+        events = ["passed", "failed", "skipped"]
17
+    }
18
+}

+ 7
- 0
exercises/isbn-verifier/src/main/java/IsbnVerifier.java 查看文件

1
+class IsbnVerifier {
2
+
3
+    boolean isValid(String stringToVerify) {
4
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
5
+    }
6
+
7
+}

+ 94
- 0
exercises/isbn-verifier/src/test/java/IsbnVerifierTest.java 查看文件

1
+import org.junit.Assert;
2
+import org.junit.Before;
3
+import org.junit.Ignore;
4
+import org.junit.Test;
5
+
6
+import static org.junit.Assert.assertTrue;
7
+import static org.junit.Assert.assertFalse;
8
+
9
+public class IsbnVerifierTest {
10
+    private IsbnVerifier isbnVerifier;
11
+
12
+    @Before
13
+    public void setUp() {
14
+        isbnVerifier = new IsbnVerifier();
15
+    }
16
+
17
+    @Test
18
+    public void validIsbnNumber() {
19
+        assertTrue(isbnVerifier.isValid("3-598-21508-8"));
20
+    }
21
+
22
+    @Ignore("Remove to run test")
23
+    @Test
24
+    public void invalidIsbnCheckDigit() {
25
+        assertFalse(isbnVerifier.isValid("3-598-21508-9"));
26
+    }
27
+
28
+    @Ignore("Remove to run test")
29
+    @Test
30
+    public void validIsbnNumberWithCheckDigitOfTen() {
31
+        assertTrue(isbnVerifier.isValid("3-598-21507-X"));
32
+    }
33
+
34
+    @Ignore("Remove to run test")
35
+    @Test
36
+    public void checkDigitIsACharacterOtherThanX() {
37
+        assertFalse(isbnVerifier.isValid("3-598-21507-A"));
38
+    }
39
+
40
+    @Ignore("Remove to run test")
41
+    @Test
42
+    public void invalidCharacterInIsbn() {
43
+        assertFalse(isbnVerifier.isValid("3-598-2K507-0"));
44
+    }
45
+
46
+    @Ignore("Remove to run test")
47
+    @Test
48
+    public void xIsOnlyValidAsACheckDigit() {
49
+        assertFalse(isbnVerifier.isValid("3-598-2X507-9"));
50
+    }
51
+
52
+    @Ignore("Remove to run test")
53
+    @Test
54
+    public void validIsbnWithoutSeparatingDashes() {
55
+        assertTrue(isbnVerifier.isValid("3598215088"));
56
+    }
57
+
58
+    @Ignore("Remove to run test")
59
+    @Test
60
+    public void isbnWithoutSeparatingDashesAndXAsCheckDigit() {
61
+        assertTrue(isbnVerifier.isValid("359821507X"));
62
+    }
63
+
64
+    @Ignore("Remove to run test")
65
+    @Test
66
+    public void isbnWithoutCheckDigitAndDashes() {
67
+        assertFalse(isbnVerifier.isValid("359821507"));
68
+    }
69
+
70
+    @Ignore("Remove to run test")
71
+    @Test
72
+    public void tooLongIsbnAndNoDashes() {
73
+        assertFalse(isbnVerifier.isValid("3598215078X"));
74
+    }
75
+
76
+    @Ignore("Remove to run test")
77
+    @Test
78
+    public void isbnWithoutCheckDigit() {
79
+        assertFalse(isbnVerifier.isValid("3-598-21507"));
80
+    }
81
+
82
+    @Ignore("Remove to run test")
83
+    @Test
84
+    public void tooLongIsbn() {
85
+        assertFalse(isbnVerifier.isValid("3-598-21507-XX"));
86
+    }
87
+
88
+    @Ignore("Remove to run test")
89
+    @Test
90
+    public void checkDigitOfXShouldNotBeUsedForZero() {
91
+        assertFalse(isbnVerifier.isValid("3-598-21515-X"));
92
+    }
93
+
94
+}

+ 1
- 0
exercises/settings.gradle 查看文件

32
 include 'hexadecimal'
32
 include 'hexadecimal'
33
 include 'hello-world'
33
 include 'hello-world'
34
 include 'house'
34
 include 'house'
35
+include 'isbn-verifier'
35
 include 'isogram'
36
 include 'isogram'
36
 include 'kindergarten-garden'
37
 include 'kindergarten-garden'
37
 include 'largest-series-product'
38
 include 'largest-series-product'