isbn-verifier
This commit is contained in:
41
elixir/isbn-verifier/lib/isbn_verifier.ex
Normal file
41
elixir/isbn-verifier/lib/isbn_verifier.ex
Normal file
@@ -0,0 +1,41 @@
|
||||
defmodule IsbnVerifier do
|
||||
@doc """
|
||||
Checks if a string is a valid ISBN-10 identifier
|
||||
|
||||
## Examples
|
||||
|
||||
iex> IsbnVerifier.isbn?("3-598-21507-X")
|
||||
true
|
||||
|
||||
iex> IsbnVerifier.isbn?("3-598-2K507-0")
|
||||
false
|
||||
|
||||
"""
|
||||
|
||||
@regex ~r/^(?<digits>\d{9})(?<check_digit>[0-9X])$/
|
||||
|
||||
@spec isbn?(String.t()) :: boolean
|
||||
def isbn?(isbn) do
|
||||
with isbn_without_dashes <- String.replace(isbn, "-", ""),
|
||||
%{"digits" => digits, "check_digit" => check_digit} <-
|
||||
Regex.named_captures(@regex, isbn_without_dashes) do
|
||||
rem(check_sum(digits) + check_digit(check_digit), 11) == 0
|
||||
else
|
||||
_ -> false
|
||||
end
|
||||
end
|
||||
|
||||
defp check_sum(digits) do
|
||||
{1, check_sum} =
|
||||
digits
|
||||
|> String.graphemes()
|
||||
|> Enum.reduce({10, 0}, fn digit, {index, acc} ->
|
||||
{index - 1, acc + String.to_integer(digit) * index}
|
||||
end)
|
||||
|
||||
check_sum
|
||||
end
|
||||
|
||||
defp check_digit("X"), do: 10
|
||||
defp check_digit(string), do: String.to_integer(string)
|
||||
end
|
||||
Reference in New Issue
Block a user