Skip to content

Commit 8a45fad

Browse files
committed
luhn redo
1 parent e078d1f commit 8a45fad

File tree

3 files changed

+29
-86
lines changed

3 files changed

+29
-86
lines changed

luhn/lib/luhn.ex

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,34 @@ defmodule Luhn do
44
"""
55
@spec valid?(String.t()) :: boolean
66
def valid?(number) do
7+
number =
8+
number
9+
|> String.replace(" ", "")
10+
|> String.graphemes()
11+
12+
state = %{
13+
digit_count: 0,
14+
sum: 0,
15+
double_digit?: length(number) |> rem(2) == 0
16+
}
17+
18+
with %{digit_count: c, sum: s} <- Enum.reduce_while(number, state, &reduce_luhn/2) do
19+
c > 1 and rem(s, 10) == 0
20+
else
21+
_ -> false
22+
end
23+
end
24+
25+
def reduce_luhn(digit, state) do
26+
with {digit, ""} <- Integer.parse(digit),
27+
digit <- (if state.double_digit?, do: digit * 2, else: digit),
28+
digit <- (if digit > 9, do: digit - 9, else: digit),
29+
sum <- state.sum + digit,
30+
digit_count <- state.digit_count + 1,
31+
double_digit? <- not state.double_digit? do
32+
{:cont, %{digit_count: digit_count, sum: sum, double_digit?: double_digit?}}
33+
else
34+
_ -> {:halt, {:error, "invalid number"}}
35+
end
736
end
837
end

luhn/luhn_test.exs

Lines changed: 0 additions & 74 deletions
This file was deleted.

luhn/test/luhn_test.exs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,62 +5,50 @@ defmodule LuhnTest do
55
refute Luhn.valid?("1")
66
end
77

8-
@tag :pending
98
test "A single zero is invalid" do
109
refute Luhn.valid?("0")
1110
end
1211

13-
@tag :pending
1412
test "a simple valid SIN that remains valid if reversed" do
1513
assert Luhn.valid?("059")
1614
end
1715

18-
@tag :pending
1916
test "a simple valid SIN that becomes invalid if reversed" do
2017
assert Luhn.valid?("59")
2118
end
2219

23-
@tag :pending
2420
test "a valid Canadian SIN" do
2521
assert Luhn.valid?("055 444 285")
2622
end
2723

28-
@tag :pending
2924
test "invalid Canadian SIN" do
3025
refute Luhn.valid?("055 444 286")
3126
end
3227

33-
@tag :pending
3428
test "invalid credit card" do
3529
refute Luhn.valid?("8273 1232 7352 0569")
3630
end
3731

38-
@tag :pending
3932
test "valid strings with a non-digit included become invalid" do
4033
refute Luhn.valid?("055a 444 285")
4134
end
4235

43-
@tag :pending
4436
test "valid strings with punctuation included become invalid" do
4537
refute Luhn.valid?("055-444-285")
4638
end
4739

48-
@tag :pending
4940
test "valid strings with symbols included become invalid" do
5041
refute Luhn.valid?("055£ 444$ 285")
5142
end
5243

53-
@tag :pending
5444
test "single zero with space is invalid" do
5545
refute Luhn.valid?(" 0")
5646
end
5747

58-
@tag :pending
5948
test "more than a single zero is valid" do
6049
assert Luhn.valid?("0000 0")
6150
end
6251

63-
@tag :pending
6452
test "input digit 9 is correctly converted to output digit 9" do
6553
assert Luhn.valid?("091")
6654
end

0 commit comments

Comments
 (0)