1 ! Copyright (c) 2012 Anonymous
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel math math.parser math.order math.ranges sequences ;
4 IN: rosetta-code.luhn-test
6 ! http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers
8 ! The Luhn test is used by some credit card companies to
9 ! distinguish valid credit card numbers from what could be a
10 ! random selection of digits.
12 ! Those companies using credit card numbers that can be
13 ! validated by the Luhn test have numbers that pass the following
16 ! 1. Reverse the order of the digits in the number.
18 ! 2. Take the first, third, ... and every other odd digit in the
19 ! reversed digits and sum them to form the partial sum s1
21 ! 3. Taking the second, fourth ... and every other even digit in
22 ! the reversed digits:
23 ! a. Multiply each digit by two and sum the digits if the
24 ! answer is greater than nine to form partial sums for the
26 ! b. Sum the partial sums of the even digits to form s2
28 ! 4. If s1 + s2 ends in zero then the original number is in the
29 ! form of a valid credit card number as verified by the Luhn test.
31 ! For example, if the trial number is 49927398716:
36 ! 6 + 7 + 9 + 7 + 9 + 4 = 42 = s1
39 ! Two times each even digit:
41 ! Sum the digits of each multiplication:
44 ! 2 + 7 + 6 + 4 + 9 = 28 = s2
46 ! s1 + s2 = 70 which ends in zero which means that 49927398716
47 ! passes the Luhn test
49 ! The task is to write a function/method/procedure/subroutine
50 ! that will validate a number with the Luhn test, and use it to
51 ! validate the following numbers:
57 : reversed-digits ( n -- list )
60 [ 10 /mod swapd suffix swap ]
63 : luhn-digit ( n -- n )
64 reversed-digits dup length iota [
66 swap odd? [ 2 * 10 /mod + ] when