The problem
An ISBN-10 (International Standard Book Number) consists of 10 digits: d1d2d3d4d5d6d7d8d9d10. The last digit, d10, is a checksum, which is calculated from the other nine digits using the following formula: (d1 *1+d2 *2+d3 *3+d4 *4+d5 *5+ d6 *6+d7 *7+d8 *8+d9 *9)%11
If the checksum is 10, the last digit is denoted as X according to the ISBN-10 convention. Write a program that prompts the user to enter the first 9 digits and displays the 10-digit ISBN (including leading zeros). Your program should read the input as an integer. Here are sample output:
Enter the first 9 digits of an ISBN as integer: 013601267
The ISBN-10 number is 0136012671
Enter the first 9 digits of an ISBN as integer: 013031997
The ISBN-10 number is 013031997X
Breaking it down
Reading input from the user and splitting a string on chars we will have the ISBN number to perform our calculation. Since we need to multiply the index of the array by the position, using IntStream.range is a way to handle it in java 8. Next calling mapToInt will transforms the string of streams to an IntStream
. Finally calling sum
, a java 8 reduction operation will sum the first 9 values together. Using total and performing a mod (modular) will find the 10th element or checkSum
. Finally combining it together to output the final format for the ISBN. Don't forget not validating the input could cause an Exception
.
public static void main(String[] strings) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the first 9 digits of an ISBN as integer: ");
String nineDigitISBN = input.next();
input.close();
String[] elements = nineDigitISBN.split("");
int total = IntStream.range(1, 10)
.mapToObj(i -> Integer.valueOf(elements[i - 1]) * i)
.mapToInt(Integer::intValue).sum();
int checkSum = total % 11;
System.out.println("The ISBN-10 number is " + nineDigitISBN
+ (checkSum == 10 ? "X" : checkSum));
}
Output
Enter the first 9 digits of an ISBN as integer: 013031997
The ISBN-10 number is 013031997X