diff --git a/config.json b/config.json index 43a06afb50..7b99fd4cfc 100644 --- a/config.json +++ b/config.json @@ -622,6 +622,19 @@ "unlocked_by": "accumulate", "uuid": "d5d48857-5325-45d2-9969-95a0d7bba370" }, + { + "core": false, + "difficulty": 4, + "slug": "isbn-verifier", + "topics": [ + "conditionals", + "loops", + "pattern_matching", + "strings" + ], + "unlocked_by": "bob", + "uuid": "d714b1e6-48b5-44d6-9661-d0acd3dd657b" + }, { "core": false, "difficulty": 5, diff --git a/exercises/Exercises.sln b/exercises/Exercises.sln index a93d8251f4..a7a10adaeb 100644 --- a/exercises/Exercises.sln +++ b/exercises/Exercises.sln @@ -220,6 +220,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CollatzConjecture", "collat EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComplexNumbers", "complex-numbers\ComplexNumbers.csproj", "{D0399EAC-5563-4234-9828-0C607BAF7623}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IsbnVerifier", "isbn-verifier\IsbnVerifier.csproj", "{72432190-8D4D-4E64-B622-F83BE80A3CBB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -662,6 +664,10 @@ Global {D0399EAC-5563-4234-9828-0C607BAF7623}.Debug|Any CPU.Build.0 = Debug|Any CPU {D0399EAC-5563-4234-9828-0C607BAF7623}.Release|Any CPU.ActiveCfg = Release|Any CPU {D0399EAC-5563-4234-9828-0C607BAF7623}.Release|Any CPU.Build.0 = Release|Any CPU + {72432190-8D4D-4E64-B622-F83BE80A3CBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72432190-8D4D-4E64-B622-F83BE80A3CBB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72432190-8D4D-4E64-B622-F83BE80A3CBB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72432190-8D4D-4E64-B622-F83BE80A3CBB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/exercises/isbn-verifier/Example.cs b/exercises/isbn-verifier/Example.cs new file mode 100644 index 0000000000..01cab30876 --- /dev/null +++ b/exercises/isbn-verifier/Example.cs @@ -0,0 +1,27 @@ +using System; +using System.Text.RegularExpressions; + +public static class IsbnVerifier +{ + public static bool IsValid(string number) + { + number = number.Replace("-", ""); + + if (!Regex.IsMatch(number, @"^(\d{9}[\dX])$")) + { + return false; + } + + var sum = 0; + var weight = 10; + var digit = 0; + for (int i = 0; i < number.Length; i++) + { + digit = (number[i] == 'X' && i == 9) ? 10 : (int)Char.GetNumericValue(number[i]); + + sum += digit * weight; + weight--; + } + return sum % 11 == 0; + } +} \ No newline at end of file diff --git a/exercises/isbn-verifier/IsbnVerifier.cs b/exercises/isbn-verifier/IsbnVerifier.cs new file mode 100644 index 0000000000..b4da9c45d6 --- /dev/null +++ b/exercises/isbn-verifier/IsbnVerifier.cs @@ -0,0 +1,9 @@ +using System; + +public static class IsbnVerifier +{ + public static bool IsValid(string number) + { + throw new NotImplementedException("You need to implement this function."); + } +} \ No newline at end of file diff --git a/exercises/isbn-verifier/IsbnVerifier.csproj b/exercises/isbn-verifier/IsbnVerifier.csproj new file mode 100644 index 0000000000..511a99e379 --- /dev/null +++ b/exercises/isbn-verifier/IsbnVerifier.csproj @@ -0,0 +1,19 @@ + + + + Exe + netcoreapp2.0 + + + + + + + + + + + + + + diff --git a/exercises/isbn-verifier/IsbnVerifierTest.cs b/exercises/isbn-verifier/IsbnVerifierTest.cs new file mode 100644 index 0000000000..931c4dbd69 --- /dev/null +++ b/exercises/isbn-verifier/IsbnVerifierTest.cs @@ -0,0 +1,84 @@ +// This file was auto-generated based on version 1.1.0 of the canonical data. + +using Xunit; + +public class IsbnVerifierTest +{ + [Fact] + public void Valid_isbn_number() + { + Assert.True(IsbnVerifier.IsValid("3-598-21508-8")); + } + + [Fact(Skip = "Remove to run test")] + public void Invalid_isbn_check_digit() + { + Assert.False(IsbnVerifier.IsValid("3-598-21508-9")); + } + + [Fact(Skip = "Remove to run test")] + public void Valid_isbn_number_with_a_check_digit_of_10() + { + Assert.True(IsbnVerifier.IsValid("3-598-21507-X")); + } + + [Fact(Skip = "Remove to run test")] + public void Check_digit_is_a_character_other_than_x() + { + Assert.False(IsbnVerifier.IsValid("3-598-21507-A")); + } + + [Fact(Skip = "Remove to run test")] + public void Invalid_character_in_isbn() + { + Assert.False(IsbnVerifier.IsValid("3-598-2K507-0")); + } + + [Fact(Skip = "Remove to run test")] + public void X_is_only_valid_as_a_check_digit() + { + Assert.False(IsbnVerifier.IsValid("3-598-2X507-9")); + } + + [Fact(Skip = "Remove to run test")] + public void Valid_isbn_without_separating_dashes() + { + Assert.True(IsbnVerifier.IsValid("3598215088")); + } + + [Fact(Skip = "Remove to run test")] + public void Isbn_without_separating_dashes_and_x_as_check_digit() + { + Assert.True(IsbnVerifier.IsValid("359821507X")); + } + + [Fact(Skip = "Remove to run test")] + public void Isbn_without_check_digit_and_dashes() + { + Assert.False(IsbnVerifier.IsValid("359821507")); + } + + [Fact(Skip = "Remove to run test")] + public void Too_long_isbn_and_no_dashes() + { + Assert.False(IsbnVerifier.IsValid("3598215078X")); + } + + [Fact(Skip = "Remove to run test")] + public void Isbn_without_check_digit() + { + Assert.False(IsbnVerifier.IsValid("3-598-21507")); + } + + [Fact(Skip = "Remove to run test")] + public void Too_long_isbn() + { + Assert.False(IsbnVerifier.IsValid("3-598-21507-XX")); + } + + [Fact(Skip = "Remove to run test")] + public void Check_digit_of_x_should_not_be_used_for_0() + { + Assert.False(IsbnVerifier.IsValid("3-598-21515-X")); + } +} \ No newline at end of file diff --git a/exercises/isbn-verifier/README.md b/exercises/isbn-verifier/README.md new file mode 100644 index 0000000000..de7c5bbf7f --- /dev/null +++ b/exercises/isbn-verifier/README.md @@ -0,0 +1,40 @@ +# ISBN Verifier + +Check if a given ISBN-10 is valid. + +## Functionality + +Given an unknown string the program should check if the provided string is a valid ISBN-10. +Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN. + +The program should allow for ISBN-10 without the separating dashes to be verified as well. + +## ISBN + +Let's take a random ISBN-10 number, say `3-598-21508-8` for this. +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. +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. +The last digit in the ISBN is the check digit which is used to detect read errors. + +The first 9 digits in the ISBN have to be between 0 and 9. +The check digit can additionally be an 'X' to allow 10 to be a valid check digit as well. + +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` +So for our example ISBN this means: +(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 = 0 + +Which proves that the ISBN is valid. + +### Submitting Exercises + +Note that, when trying to submit an exercise, make sure the exercise file that you're submitting is in the `exercism/csharp/` directory. + +For example, if you're submitting `bob.cs` for the Bob exercise, the submit command would be something like `exercism submit /csharp/bob/bob.cs`. + +## Source + +Wikipedia [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) + +## Submitting Incomplete Solutions + +It's possible to submit an incomplete solution so you can see how others have completed the exercise. \ No newline at end of file diff --git a/generators/Exercises/IsbnVerifier.cs b/generators/Exercises/IsbnVerifier.cs new file mode 100644 index 0000000000..a3e451c107 --- /dev/null +++ b/generators/Exercises/IsbnVerifier.cs @@ -0,0 +1,15 @@ +using Generators.Input; + +namespace Generators.Exercises +{ + public class IsbnVerifier : Exercise + { + protected override void UpdateCanonicalData(CanonicalData canonicalData) + { + foreach (var canonicalDataCase in canonicalData.Cases) + { + canonicalDataCase.Property = "IsValid"; + } + } + } +}