main
1require "spec_helper"
2
3# The Luhn test is used by some credit card companies to
4# distinguish valid credit card numbers from what could
5# be a random selection of digits.
6#
7# For example, if the trial number is 49927398716:
8#
9# 1. Reverse the digits:
10# 61789372994
11# 2. Sum the odd digits:
12# 6 + 7 + 9 + 7 + 9 + 4 = 42 = s1
13# 3. The even digits:
14# 1, 8, 3, 2, 9
15# 4. Two times each even digit:
16# 2, 16, 6, 4, 18
17# 5. Sum the digits of each multiplication:
18# 2, 7, 6, 4, 9
19# 6. Sum the last:
20# 2 + 7 + 6 + 4 + 9 = 28 = s2
21#
22# s1 + s2 = 70 which ends in zero which means {
23# that 49927398716 passes the Luhn test
24
25
26class Luhn
27 def self.valid?(credit_card)
28 step_2, step_3 = partition(credit_card.digits)
29 (step_2.sum + step_3.map { |x| x * 2 }.map { |x| x.digits.sum }.sum).digits[0].zero?
30 end
31
32 def self.partition(digits)
33 digits.each_with_index.inject([[], []]) do |memo, (digit, index)|
34 memo[index.even? ? 0 : 1].push(digit)
35 memo
36 end
37 end
38end
39
40RSpec.describe Luhn do
41 subject { Luhn }
42
43 describe ".valid?" do
44 specify { expect(subject).to be_valid(49927398716) }
45 specify { expect(subject).not_to be_valid(49927398717) }
46 specify { expect(subject).not_to be_valid(1234567812345678) }
47 specify { expect(subject).to be_valid(1234567812345670) }
48 end
49end