Task

For each number list of 6-digit SEDOLs, calculate and append the checksum digit.



That is, given this input:

710889
B0YBKJ
406566
B0YBLH
228276
B0YBKL
557910
B0YBKR
585284
B0YBKT
B00030

Produce this output:

7108899
B0YBKJ7
4065663
B0YBLH2
2282765
B0YBKL9
5579107
B0YBKR5
5852842
B0YBKT7
B000300

Extra credit

Check each input is correctly formed, especially with respect to valid characters allowed in a SEDOL string.



Related tasks

   Luhn test
   ISIN


 
#DEFINE ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#DEFINE VOWELS "AEIOU"
#DEFINE VALIDCHARS "0123456789" + ALPHABET
LOCAL cMsg As String, cCode As String 
LOCAL ARRAY codes[12]
codes[1] = "710889"
codes[2] = "B0YBKJ"
codes[3] = "406566"
codes[4] = "B0YBLH"
codes[5] = "228276"
codes[6] = "B0YBKL"
codes[7] = "557910"
codes[8] = "B0YBKR"
codes[9] = "585284"
codes[10] = "B0YBKT"
codes[11] = "B00030"
codes[12] = "B0030A"
DIMENSION w[6]
w[1] = 1
w[2] = 3
w[3] = 1
w[4] = 7
w[5] = 3
w[6] = 9
CLEAR
FOR EACH cCode IN codes
    cMsg = ""
    IF IsValidCode(@cCode, @cMsg)	&& Parameters passed by reference
	cCode = cCode + GetCheckDigit(cCode)
	? cCode
    ELSE
	? cCode, cMsg
    ENDIF			
ENDFOR
 
FUNCTION GetCheckDigit(tcCode As String) As String
LOCAL i As Integer, c As String, s As Integer, k As Integer
s = 0
FOR i = 1 TO 6
    c = SUBSTR(tcCode, i, 1)
    IF ISDIGIT(c)
	k = VAL(c)
    ELSE
	k = 9 + AT(c, ALPHABET)
    ENDIF
    s = s + k*w[i]
ENDFOR
RETURN TRANSFORM((10 - s%10)%10)
ENDFUNC 
 
FUNCTION IsValidCode(tcCode As String, tcMsg As String) As Boolean
LOCAL n As Integer, c As String, i As Integer
*!* Get rid of any spaces and convert to upper case
tcCode = UPPER(STRTRAN(tcCode, " "))
n = LEN(tcCode)
IF LEN(tcCode) # 6
    tcMsg = "Code must be 6 characters."
ELSE
    FOR i = 1 TO n
	c = SUBSTR(tcCode, i, 1)
	IF NOT c $ VALIDCHAR
	    tcMsg = c + " is not a valid character."
	    EXIT 
	ELSE
	    IF c $ VOWELS
		tcMsg = "Vowels are not allowed."
		EXIT 
	    ENDIF
	ENDIF 			
    ENDFOR
ENDIF
RETURN EMPTY(tcMsg)
ENDFUNC	
 