Background
Luhn's Algorithm is a simple check digit formula used to validate a variety of identification numbers. In standard Luhn, each second digit from the end is doubled, and then the digits of all numbers are summed. If the sum mod 10 is 0, the algorithm passes.
I did some math and found that multiplying by two is not the only method that creates an ordering of the digits. In fact, anything not divisible by a nontrivial divisor of 10 - 1 works.
Your Task
You will be given a base B
and a list of numbers less than B
representing the digits. Now, for each number N
, do the following:
Let
I
be the 1-based distance of that number to the end of the list. So the last value would haveI = 1
, the second-to-last value would haveI = 2
, etc.Let
Factor = I / gcd(I, B - 1)
. Repeat this division by a GCD as necessary to eliminate any common factors, as in the case whereB - 1
dividesI
multiple times. Only numbers co-prime toB - 1
work, so this convertsI
to the "closest" coprime version.In other words, remove any factors that are shared with
B - 1
.Multiply the number
N
byFactor
, then repeatedly sum the digits (in baseB
) until only one remains.
You should have exactly the same number of digits as the original list. Sum them, and if the result % B
is zero, the checksum passes. If it is any other value, it fails.
You may assume that base >= 3
and that the input list is non-empty.
Test Cases
Truthy:
[[1, 4, 1], 12],
[[7, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9], 12],
[[10, 2, 3, 4, 5], 12],
[[10, 2, 3, 4, 8], 11]
Falsy:
[[1, 4, 1, 1], 12],
[[7, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10], 12],
[[10, 2, 3, 4, 5], 11],
[[0, 2, 3, 3, 5], 11]
As this is a decision-problem, you may choose to invert the output if you desire.
Worked Out Example
Starting list: [7, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9]
, base: 12
The indices with factors shared with 11
removed, shown here in reverse, are:
1 2 3 4 5 6 7 8 9 10 1 12
Then multiplying and taking the digital root, still with the terms shown in reverse:
9 9 5 10 2 3 2 10 5 9 1 7
Finally, the cumulative sums mod 12 are:
9 6 11 9 11 2 4 2 7 4 5 0
The final sum is 0, so this example passes the checksum.
gcd(I / gcd(I, B-1), B-1)
is always1
? \$\endgroup\$