Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/SEDOLs/00-META.yaml
Normal file
3
Task/SEDOLs/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/SEDOLs
|
||||
note: Checksums
|
||||
42
Task/SEDOLs/00-TASK.txt
Normal file
42
Task/SEDOLs/00-TASK.txt
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
;Task:
|
||||
For each number list of '''6'''-digit [[wp:SEDOL|SEDOL]]s, calculate and append the checksum digit.
|
||||
|
||||
|
||||
That is, given this input:
|
||||
<pre>
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030
|
||||
</pre>
|
||||
Produce this output:
|
||||
<pre>
|
||||
7108899
|
||||
B0YBKJ7
|
||||
4065663
|
||||
B0YBLH2
|
||||
2282765
|
||||
B0YBKL9
|
||||
5579107
|
||||
B0YBKR5
|
||||
5852842
|
||||
B0YBKT7
|
||||
B000300
|
||||
</pre>
|
||||
|
||||
;Extra credit:
|
||||
Check each input is correctly formed, especially with respect to valid characters allowed in a SEDOL string.
|
||||
|
||||
|
||||
;Related tasks:
|
||||
* [[Luhn test]]
|
||||
* [[Calculate International Securities Identification Number|ISIN]]
|
||||
<br><br>
|
||||
|
||||
24
Task/SEDOLs/11l/sedols.11l
Normal file
24
Task/SEDOLs/11l/sedols.11l
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
F char2value(c)
|
||||
assert(c !C ‘AEIOU’, ‘No vowels’)
|
||||
R Int(c, radix' 36)
|
||||
|
||||
V sedolweight = [1, 3, 1, 7, 3, 9]
|
||||
|
||||
F checksum(sedol)
|
||||
V tmp = sum(zip(sedol, :sedolweight).map((ch, weight) -> char2value(ch) * weight))
|
||||
R String((10 - (tmp % 10)) % 10)
|
||||
|
||||
V sedols =
|
||||
|‘710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT’
|
||||
|
||||
L(sedol) sedols.split("\n")
|
||||
print(sedol‘’checksum(sedol))
|
||||
58
Task/SEDOLs/ALGOL-68/sedols.alg
Normal file
58
Task/SEDOLs/ALGOL-68/sedols.alg
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
[]INT sedol weights = (1, 3, 1, 7, 3, 9);
|
||||
STRING reject = "AEIOUaeiou";
|
||||
|
||||
PROC strcspn = (STRING s,reject)INT: (
|
||||
INT out:=0;
|
||||
FOR i TO UPB s DO
|
||||
IF char in string(s[i], LOC INT, reject) THEN
|
||||
return out
|
||||
FI;
|
||||
out:=i
|
||||
OD;
|
||||
return out: out
|
||||
);
|
||||
|
||||
PROC sedol checksum = (REF STRING sedol6)INT:
|
||||
(
|
||||
INT out;
|
||||
|
||||
INT len := UPB sedol6;
|
||||
INT sum := 0;
|
||||
|
||||
IF sedol6[len-1] = REPR 10 THEN len-:=1; sedol6[len]:=null char FI;
|
||||
IF len = 7 THEN
|
||||
putf(stand error, ($"SEDOL code already checksummed? ("g")"l$, sedol6));
|
||||
out := ABS ( BIN ABS sedol6[6] AND 16r7f); return out
|
||||
FI;
|
||||
IF len > 7 OR len < 6 OR strcspn(sedol6, reject) /= 6 THEN
|
||||
putf(stand error, ($"not a SEDOL code? ("g")"l$, sedol6));
|
||||
out := -1; return out
|
||||
FI;
|
||||
FOR i TO UPB sedol6 DO
|
||||
sum+:=sedol weights[i]*
|
||||
IF is digit(sedol6[i]) THEN
|
||||
ABS sedol6[i]- ABS "0"
|
||||
ELIF is alpha(sedol6[i]) THEN
|
||||
(ABS to upper(sedol6[i])-ABS "A") + 10
|
||||
ELSE
|
||||
putf(stand error, $"SEDOL with not alphanumeric digit"l$);
|
||||
out:=-1; return out
|
||||
FI
|
||||
OD;
|
||||
out := (10 - (sum MOD 10)) MOD 10 + ABS "0";
|
||||
return out: out
|
||||
);
|
||||
|
||||
main:
|
||||
(
|
||||
STRING line;
|
||||
|
||||
on logical file end(stand in, (REF FILE f)BOOL: done);
|
||||
DO getf(stand in, ($gl$,line));
|
||||
INT sr := sedol checksum(line);
|
||||
IF sr > 0 THEN
|
||||
printf(($ggl$, line, REPR sedol checksum(line)))
|
||||
FI
|
||||
OD;
|
||||
done: SKIP
|
||||
)
|
||||
43
Task/SEDOLs/ALGOL-W/sedols.alg
Normal file
43
Task/SEDOLs/ALGOL-W/sedols.alg
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
begin
|
||||
% returns the check digit for the specified SEDOL %
|
||||
string(1) procedure sedolCheckDigit ( string(6) value sedol ) ;
|
||||
begin
|
||||
integer checkSum, checkDigit;
|
||||
checkSum := 0;
|
||||
for cPos := 0 until 5 do begin
|
||||
string(1) c;
|
||||
integer digit;
|
||||
c := sedol( cPos // 1 );
|
||||
if c >= "0" and c <= "9"
|
||||
then digit := decode( c ) - decode( "0" )
|
||||
else digit := 10 + ( decode( c ) - decode( "A" ) );
|
||||
checkSum := checkSum + ( ( case cPos + 1 of ( 1, 3, 1, 7, 3, 9 ) ) * digit )
|
||||
end for_cPos ;
|
||||
checkDigit := ( 10 - ( checkSum rem 10 ) ) rem 10;
|
||||
if checkDigit < 10
|
||||
then code( decode( "0" ) + checkDigit )
|
||||
else code( decode( "A" ) + ( checkDigit - 10 ) )
|
||||
end sedolCheckDigit ;
|
||||
|
||||
% task test cases %
|
||||
|
||||
procedure testCheckDigit ( string(6) value sedol; string(1) value expectedCheckDigit ) ;
|
||||
begin
|
||||
string(1) checkDigit;
|
||||
checkDigit := sedolCheckDigit( sedol );
|
||||
write( s_w := 0, sedol, checkDigit );
|
||||
if checkDigit not = expectedCheckDigit then writeon( " ?? expected: ", expectedCheckDigit )
|
||||
end testCheckDigit ;
|
||||
|
||||
testCheckDigit( "710889", "9" );
|
||||
testCheckDigit( "B0YBKJ", "7" );
|
||||
testCheckDigit( "406566", "3" );
|
||||
testCheckDigit( "B0YBLH", "2" );
|
||||
testCheckDigit( "228276", "5" );
|
||||
testCheckDigit( "B0YBKL", "9" );
|
||||
testCheckDigit( "557910", "7" );
|
||||
testCheckDigit( "B0YBKR", "5" );
|
||||
testCheckDigit( "585284", "2" );
|
||||
testCheckDigit( "B0YBKT", "7" );
|
||||
testCheckDigit( "B00030", "0" )
|
||||
end.
|
||||
49
Task/SEDOLs/AWK/sedols.awk
Normal file
49
Task/SEDOLs/AWK/sedols.awk
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
function ord(a)
|
||||
{
|
||||
return amap[a]
|
||||
}
|
||||
|
||||
function sedol_checksum(sed)
|
||||
{
|
||||
sw[1] = 1; sw[2] = 3; sw[3] = 1
|
||||
sw[4] = 7; sw[5] = 3; sw[6] = 9
|
||||
sum = 0
|
||||
for(i=1; i <= 6; i++) {
|
||||
c = substr(toupper(sed), i, 1)
|
||||
if ( c ~ /[[:digit:]]/ ) {
|
||||
sum += c*sw[i]
|
||||
} else {
|
||||
sum += (ord(c)-ord("A")+10)*sw[i]
|
||||
}
|
||||
}
|
||||
return (10 - (sum % 10)) % 10
|
||||
}
|
||||
|
||||
BEGIN { # prepare amap for ord
|
||||
for(_i=0;_i<256;_i++) {
|
||||
astr = sprintf("%c", _i)
|
||||
amap[astr] = _i
|
||||
}
|
||||
}
|
||||
|
||||
/[AEIOUaeiou]/ {
|
||||
print "'" $0 "' not a valid SEDOL code"
|
||||
next
|
||||
}
|
||||
{
|
||||
if ( (length($0) > 7) || (length($0) < 6) ) {
|
||||
print "'" $0 "' is too long or too short to be valid SEDOL"
|
||||
next
|
||||
}
|
||||
sedol = substr($0, 1, 6)
|
||||
sedolcheck = sedol_checksum(sedol)
|
||||
if ( length($0) == 7 ) {
|
||||
if ( (sedol sedolcheck) != $0 ) {
|
||||
print sedol sedolcheck " (original " $0 " has wrong check digit"
|
||||
} else {
|
||||
print sedol sedolcheck
|
||||
}
|
||||
} else {
|
||||
print sedol sedolcheck
|
||||
}
|
||||
}
|
||||
59
Task/SEDOLs/Action-/sedols.action
Normal file
59
Task/SEDOLs/Action-/sedols.action
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
INT FUNC SedolChecksum(CHAR ARRAY sedol)
|
||||
BYTE ARRAY weights=[1 3 1 7 3 9]
|
||||
INT i,sum
|
||||
CHAR c
|
||||
|
||||
IF sedol(0)#6 THEN
|
||||
RETURN (-1)
|
||||
FI
|
||||
|
||||
sum=0
|
||||
FOR i=1 TO sedol(0)
|
||||
DO
|
||||
c=sedol(i)
|
||||
IF c>='0 AND c<='9 THEN
|
||||
sum==+(c-'0)*weights(i-1)
|
||||
ELSE
|
||||
IF c>='a AND c<='z THEN
|
||||
c==-'a-'A
|
||||
FI
|
||||
IF c='A OR c='E OR c='I OR c='O OR c='U THEN
|
||||
RETURN (-1)
|
||||
ELSEIF c>='A AND c<='Z THEN
|
||||
sum==+(c-'A+10)*weights(i-1)
|
||||
ELSE
|
||||
RETURN (-1)
|
||||
FI
|
||||
FI
|
||||
OD
|
||||
sum=(10-(sum MOD 10)) MOD 10
|
||||
RETURN (sum)
|
||||
|
||||
PROC Test(CHAR ARRAY sedol)
|
||||
INT res
|
||||
|
||||
res=SedolChecksum(sedol)
|
||||
Print(sedol) Print(" -> ")
|
||||
IF res>=0 THEN
|
||||
Print(sedol) PrintIE(res)
|
||||
ELSE
|
||||
PrintE("invalid input")
|
||||
FI
|
||||
RETURN
|
||||
|
||||
PROC Main()
|
||||
Test("710889")
|
||||
Test("B0YBKJ")
|
||||
Test("406566")
|
||||
Test("B0YBLH")
|
||||
Test("228276")
|
||||
Test("B0YBKL")
|
||||
Test("557910")
|
||||
Test("B0YBKR")
|
||||
Test("585284")
|
||||
Test("B0YBKT")
|
||||
Test("B00030")
|
||||
Test("12345A")
|
||||
Test("12345")
|
||||
Test("1234567")
|
||||
RETURN
|
||||
50
Task/SEDOLs/ActionScript/sedols.as
Normal file
50
Task/SEDOLs/ActionScript/sedols.as
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
//Return the code corresponding to a given character.
|
||||
//ActionScript does not have a character type, so 1-digit strings
|
||||
//are used instead
|
||||
function toSEDOLCode(char:String):uint {
|
||||
//Make sure only a single character was sent.
|
||||
if(char.length != 1)
|
||||
throw new Error("toSEDOL expected string length of 1, got " + char.length);
|
||||
//Character is uppercase
|
||||
if (char >= "A" && char <= "Z") {
|
||||
return SEDOL.charCodeAt() + 10 - "A".charCodeAt();
|
||||
}
|
||||
//Character is numeric
|
||||
else if (char >= "0" && char <= "9"){
|
||||
return uint(char);
|
||||
}
|
||||
//Error: character is neither numeric nor uppercase
|
||||
else{
|
||||
throw new Error("toSEDOLCode expected numeric or uppercase character, recieved " + char);
|
||||
}
|
||||
}
|
||||
//Calculate the weighted sum for the SEDOL.
|
||||
function toSum(str:String):uint {
|
||||
if(str.length != 6)
|
||||
throw new Error("toSum expected length 6, recieved " + str.length);
|
||||
var sum:uint=0;
|
||||
for (var i:uint = 0; i < str.length; i++)
|
||||
sum+=toSEDOLCode(str.charAt(i))*[1,3,1,7,3,9][i];
|
||||
return sum;
|
||||
}
|
||||
//Calculate the check digit from the weighted sum.
|
||||
function toCheck(num:int):uint
|
||||
{
|
||||
return (10 -(num % 10)) % 10;
|
||||
}
|
||||
//Print the SEDOL with the check digit added.
|
||||
function printWithCheck(SEDOL:String):void
|
||||
{
|
||||
trace(SEDOL + toCheck(toSum(SEDOL)));
|
||||
}
|
||||
printWithCheck("710889");
|
||||
printWithCheck("B0YBKJ");
|
||||
printWithCheck("406566");
|
||||
printWithCheck("B0YBLH");
|
||||
printWithCheck("228276");
|
||||
printWithCheck("B0YBKL");
|
||||
printWithCheck("557910");
|
||||
printWithCheck("B0YBKR");
|
||||
printWithCheck("585284");
|
||||
printWithCheck("B0YBKT");
|
||||
printWithCheck("B00030");
|
||||
40
Task/SEDOLs/Ada/sedols.ada
Normal file
40
Task/SEDOLs/Ada/sedols.ada
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
|
||||
procedure Test_SEDOL is
|
||||
|
||||
subtype SEDOL_String is String (1..6);
|
||||
type SEDOL_Sum is range 0..9;
|
||||
|
||||
function Check (SEDOL : SEDOL_String) return SEDOL_Sum is
|
||||
Weight : constant array (SEDOL_String'Range) of Integer := (1,3,1,7,3,9);
|
||||
Sum : Integer := 0;
|
||||
Item : Integer;
|
||||
begin
|
||||
for Index in SEDOL'Range loop
|
||||
Item := Character'Pos (SEDOL (Index));
|
||||
case Item is
|
||||
when Character'Pos ('0')..Character'Pos ('9') =>
|
||||
Item := Item - Character'Pos ('0');
|
||||
when Character'Pos ('B')..Character'Pos ('D') |
|
||||
Character'Pos ('F')..Character'Pos ('H') |
|
||||
Character'Pos ('J')..Character'Pos ('N') |
|
||||
Character'Pos ('P')..Character'Pos ('T') |
|
||||
Character'Pos ('V')..Character'Pos ('Z') =>
|
||||
Item := Item - Character'Pos ('A') + 10;
|
||||
when others =>
|
||||
raise Constraint_Error;
|
||||
end case;
|
||||
Sum := Sum + Item * Weight (Index);
|
||||
end loop;
|
||||
return SEDOL_Sum ((-Sum) mod 10);
|
||||
end Check;
|
||||
|
||||
Test : constant array (1..10) of SEDOL_String :=
|
||||
( "710889", "B0YBKJ", "406566", "B0YBLH", "228276",
|
||||
"B0YBKL", "557910", "B0YBKR", "585284", "B0YBKT"
|
||||
);
|
||||
begin
|
||||
for Index in Test'Range loop
|
||||
Put_Line (Test (Index) & Character'Val (Character'Pos ('0') + Check (Test (Index))));
|
||||
end loop;
|
||||
end Test_SEDOL;
|
||||
43
Task/SEDOLs/AppleScript/sedols-1.applescript
Normal file
43
Task/SEDOLs/AppleScript/sedols-1.applescript
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
on appendCheckDigitToSEDOL(sedol)
|
||||
if ((count sedol) is not 6) then ¬
|
||||
return {false, "Error in appendCheckDigitToSEDOL handler: " & sedol & " doesn't have 6 characters."}
|
||||
set chars to "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
set vowels to "AEIOU"
|
||||
set weights to {1, 3, 1, 7, 3, 9}
|
||||
|
||||
set s to 0
|
||||
considering diacriticals but ignoring case -- In case these are set otherwise when this handler's called.
|
||||
repeat with i from 1 to 6
|
||||
set thisCharacter to character i of sedol
|
||||
set o to (offset of thisCharacter in chars)
|
||||
if ((o is 0) or (thisCharacter is in vowels)) then ¬
|
||||
return {false, "Error in appendCheckDigitToSEDOL handler: " & sedol & " contains invalid character(s)."}
|
||||
set s to s + (o - 1) * (item i of weights)
|
||||
end repeat
|
||||
end considering
|
||||
|
||||
return {true, sedol & ((10 - (s mod 10)) mod 10)}
|
||||
end appendCheckDigitToSEDOL
|
||||
|
||||
-- Test code:
|
||||
set input to "710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030"
|
||||
set output to {}
|
||||
repeat with thisSEDOL in paragraphs of input
|
||||
set {valid, theResult} to appendCheckDigitToSEDOL(thisSEDOL)
|
||||
set end of output to theResult
|
||||
end repeat
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to linefeed
|
||||
set output to output as text
|
||||
set AppleScript's text item delimiters to astid
|
||||
return output
|
||||
11
Task/SEDOLs/AppleScript/sedols-2.applescript
Normal file
11
Task/SEDOLs/AppleScript/sedols-2.applescript
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"7108899
|
||||
B0YBKJ7
|
||||
4065663
|
||||
B0YBLH2
|
||||
2282765
|
||||
B0YBKL9
|
||||
5579107
|
||||
B0YBKR5
|
||||
5852842
|
||||
B0YBKT7
|
||||
B000300"
|
||||
25
Task/SEDOLs/Arturo/sedols.arturo
Normal file
25
Task/SEDOLs/Arturo/sedols.arturo
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
ord0: to :integer `0`
|
||||
ord7: to :integer `7`
|
||||
c2v: function [c][
|
||||
ordC: to :integer c
|
||||
if? c < `A` -> return ordC - ord0
|
||||
else -> return ordC - ord7
|
||||
]
|
||||
|
||||
weight: [1 3 1 7 3 9]
|
||||
|
||||
checksum: function [sedol][
|
||||
val: new 0
|
||||
loop .with:'i sedol 'ch ->
|
||||
'val + weight\[i] * c2v ch
|
||||
return to :char ord0 + (10 - val % 10) % 10
|
||||
]
|
||||
|
||||
sedols: [
|
||||
"710889" "B0YBKJ" "406566" "B0YBLH"
|
||||
"228276" "B0YBKL" "557910" "B0YBKR"
|
||||
"585284" "B0YBKT" "B00030"
|
||||
]
|
||||
|
||||
loop sedols 'sed ->
|
||||
print [sed "->" sed ++ checksum sed]
|
||||
19
Task/SEDOLs/AutoHotkey/sedols-1.ahk
Normal file
19
Task/SEDOLs/AutoHotkey/sedols-1.ahk
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
codes = 710889,B0YBKJ,406566,B0YBLH,228276,B0YBKL,557910,B0YBKR,585284,B0YBKT,B00030,ABCDEF,BBBBBBB
|
||||
Loop, Parse, codes, `,
|
||||
output .= A_LoopField "`t-> " SEDOL(A_LoopField) "`n"
|
||||
Msgbox %output%
|
||||
|
||||
SEDOL(code) {
|
||||
Static weight1:=1, weight2:=3, weight3:=1, weight4:=7, weight5:=3, weight6:=9
|
||||
If (StrLen(code) != 6)
|
||||
Return "Invalid length."
|
||||
StringCaseSense On
|
||||
Loop, Parse, code
|
||||
If A_LoopField is Number
|
||||
check_digit += A_LoopField * weight%A_Index%
|
||||
Else If A_LoopField in B,C,D,F,G,H,J,K,L,M,N,P,Q,R,S,T,V,W,X,Y,Z
|
||||
check_digit += (Asc(A_LoopField)-Asc("A") + 10) * weight%A_Index%
|
||||
Else
|
||||
Return "Invalid character."
|
||||
Return code . Mod(10-Mod(check_digit,10),10)
|
||||
}
|
||||
17
Task/SEDOLs/AutoHotkey/sedols-2.ahk
Normal file
17
Task/SEDOLs/AutoHotkey/sedols-2.ahk
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
MsgBox % SEDOL("710889") ;7108899
|
||||
MsgBox % SEDOL("B0YBKJ") ;B0YBKJ7
|
||||
MsgBox % SEDOL("406566") ;4065663
|
||||
MsgBox % SEDOL("B0YBLH") ;B0YBLH2
|
||||
MsgBox % SEDOL("228276") ;2282765
|
||||
MsgBox % SEDOL("B0YBKL") ;B0YBKL9
|
||||
MsgBox % SEDOL("557910") ;5579107
|
||||
MsgBox % SEDOL("B0YBKR") ;B0YBKR5
|
||||
MsgBox % SEDOL("585284") ;5852842
|
||||
MsgBox % SEDOL("B0YBKT") ;B0YBKT7
|
||||
|
||||
SEDOL(w) {
|
||||
static weights := [1,3,1,7,3,9]
|
||||
loop parse, w
|
||||
s += ((c := Asc(A_LoopField)) >= 65 ? c - 65 + 10 : c - 48) * weights[A_Index]
|
||||
return w Mod(10 - Mod(s, 10), 10)
|
||||
}
|
||||
31
Task/SEDOLs/BASIC/sedols.basic
Normal file
31
Task/SEDOLs/BASIC/sedols.basic
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
DECLARE FUNCTION getSedolCheckDigit! (str AS STRING)
|
||||
DO
|
||||
INPUT a$
|
||||
PRINT a$ + STR$(getSedolCheckDigit(a$))
|
||||
LOOP WHILE a$ <> ""
|
||||
|
||||
FUNCTION getSedolCheckDigit (str AS STRING)
|
||||
IF LEN(str) <> 6 THEN
|
||||
PRINT "Six chars only please"
|
||||
EXIT FUNCTION
|
||||
END IF
|
||||
str = UCASE$(str)
|
||||
DIM mult(6) AS INTEGER
|
||||
mult(1) = 1: mult(2) = 3: mult(3) = 1
|
||||
mult(4) = 7: mult(5) = 3: mult(6) = 9
|
||||
total = 0
|
||||
FOR i = 1 TO 6
|
||||
s$ = MID$(str, i, 1)
|
||||
IF s$ = "A" OR s$ = "E" OR s$ = "I" OR s$ = "O" OR s$ = "U" THEN
|
||||
PRINT "No vowels"
|
||||
EXIT FUNCTION
|
||||
END IF
|
||||
IF ASC(s$) >= 48 AND ASC(s$) <= 57 THEN
|
||||
total = total + VAL(s$) * mult(i)
|
||||
ELSE
|
||||
total = total + (ASC(s$) - 55) * mult(i)
|
||||
END IF
|
||||
|
||||
NEXT i
|
||||
getSedolCheckDigit = (10 - (total MOD 10)) MOD 10
|
||||
END FUNCTION
|
||||
21
Task/SEDOLs/BBC-BASIC/sedols.basic
Normal file
21
Task/SEDOLs/BBC-BASIC/sedols.basic
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
PRINT FNsedol("710889")
|
||||
PRINT FNsedol("B0YBKJ")
|
||||
PRINT FNsedol("406566")
|
||||
PRINT FNsedol("B0YBLH")
|
||||
PRINT FNsedol("228276")
|
||||
PRINT FNsedol("B0YBKL")
|
||||
PRINT FNsedol("557910")
|
||||
PRINT FNsedol("B0YBKR")
|
||||
PRINT FNsedol("585284")
|
||||
PRINT FNsedol("B0YBKT")
|
||||
PRINT FNsedol("B00030")
|
||||
END
|
||||
|
||||
DEF FNsedol(d$)
|
||||
LOCAL a%, i%, s%, weights%()
|
||||
DIM weights%(6) : weights%() = 0, 1, 3, 1, 7, 3, 9
|
||||
FOR i% = 1 TO 6
|
||||
a% = ASCMID$(d$,i%) - &30
|
||||
s% += (a% + 7 * (a% > 9)) * weights%(i%)
|
||||
NEXT
|
||||
= d$ + CHR$(&30 + (10 - s% MOD 10) MOD 10)
|
||||
43
Task/SEDOLs/C++/sedols.cpp
Normal file
43
Task/SEDOLs/C++/sedols.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#include <numeric>
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
|
||||
template<typename result_sink_t>
|
||||
auto sedol_checksum(std::string const& sedol, result_sink_t result_sink)
|
||||
{
|
||||
if(sedol.size() != 6)
|
||||
return result_sink(0, "length of sedol string != 6");
|
||||
|
||||
const char * valid_chars = "BCDFGHJKLMNPQRSTVWXYZ0123456789";
|
||||
if(sedol.find_first_not_of(valid_chars) != std::string::npos)
|
||||
return result_sink(0, "sedol string contains disallowed characters");
|
||||
|
||||
const int weights[] = {1,3,1,7,3,9};
|
||||
auto weighted_sum = std::inner_product(sedol.begin(), sedol.end(), weights, 0
|
||||
, [](int acc, int prod){ return acc + prod; }
|
||||
, [](char c, int weight){ return (std::isalpha(c) ? c -'A' + 10 : c - '0') * weight; }
|
||||
);
|
||||
return result_sink((10 - (weighted_sum % 10)) % 10, nullptr);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std;
|
||||
string inputs[] = {
|
||||
"710889", "B0YBKJ", "406566", "B0YBLH", "228276", "B0YBKL",
|
||||
"557910", "B0YBKR", "585284", "B0YBKT", "B00030"
|
||||
};
|
||||
for(auto const & sedol : inputs)
|
||||
{
|
||||
sedol_checksum(sedol, [&](auto sum, char const * errorMessage)
|
||||
{
|
||||
if(errorMessage)
|
||||
cout << "error for sedol: " << sedol << " message: " << errorMessage << "\n";
|
||||
else
|
||||
cout << sedol << sum << "\n";
|
||||
});
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
27
Task/SEDOLs/C-sharp/sedols.cs
Normal file
27
Task/SEDOLs/C-sharp/sedols.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
static int[] sedol_weights = { 1, 3, 1, 7, 3, 9 };
|
||||
static int sedolChecksum(string sedol)
|
||||
{
|
||||
int len = sedol.Length;
|
||||
int sum = 0;
|
||||
|
||||
if (len == 7) //SEDOL code already checksummed?
|
||||
return (int)sedol[6];
|
||||
|
||||
if ((len > 7) || (len < 6) || System.Text.RegularExpressions.Regex.IsMatch(sedol, "[AEIOUaeiou]+")) //invalid SEDOL
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (Char.IsDigit(sedol[i]))
|
||||
sum += (((int)sedol[i] - 48) * sedol_weights[i]);
|
||||
|
||||
else if (Char.IsLetter(sedol[i]))
|
||||
sum += (((int)Char.ToUpper(sedol[i]) - 55) * sedol_weights[i]);
|
||||
|
||||
else
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
return (10 - (sum % 10)) % 10;
|
||||
}
|
||||
48
Task/SEDOLs/C/sedols.c
Normal file
48
Task/SEDOLs/C/sedols.c
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
int sedol_weights[] = {1, 3, 1, 7, 3, 9};
|
||||
const char *reject = "AEIOUaeiou";
|
||||
|
||||
int sedol_checksum(const char *sedol6)
|
||||
{
|
||||
int len = strlen(sedol6);
|
||||
int sum = 0, i;
|
||||
|
||||
if ( len == 7 ) {
|
||||
fprintf(stderr, "SEDOL code already checksummed? (%s)\n", sedol6);
|
||||
return sedol6[6] & 0x7f;
|
||||
}
|
||||
if ( (len > 7) || (len < 6) || ( strcspn(sedol6, reject) != 6 )) {
|
||||
fprintf(stderr, "not a SEDOL code? (%s)\n", sedol6);
|
||||
return -1;
|
||||
}
|
||||
for(i=0; i < 6; i++) {
|
||||
if ( isdigit(sedol6[i]) ) {
|
||||
sum += (sedol6[i]-'0')*sedol_weights[i];
|
||||
} else if ( isalpha(sedol6[i]) ) {
|
||||
sum += ((toupper(sedol6[i])-'A') + 10)*sedol_weights[i];
|
||||
} else {
|
||||
fprintf(stderr, "SEDOL with not alphanumeric digit\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return (10 - (sum%10))%10 + '0';
|
||||
}
|
||||
|
||||
|
||||
#define MAXLINELEN 10
|
||||
int main()
|
||||
{
|
||||
char line[MAXLINELEN];
|
||||
int sr, len;
|
||||
while( fgets(line, MAXLINELEN, stdin) != NULL ) {
|
||||
len = strlen(line);
|
||||
if ( line[len-1] == '\n' ) line[len-1]='\0';
|
||||
sr = sedol_checksum(line);
|
||||
if ( sr > 0 )
|
||||
printf("%s%c\n", line, sr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
79
Task/SEDOLs/COBOL/sedols.cobol
Normal file
79
Task/SEDOLs/COBOL/sedols.cobol
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
>>SOURCE FREE
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. sedol.
|
||||
|
||||
ENVIRONMENT DIVISION.
|
||||
INPUT-OUTPUT SECTION.
|
||||
FILE-CONTROL.
|
||||
SELECT sedol-file ASSIGN "sedol.txt"
|
||||
ORGANIZATION LINE SEQUENTIAL
|
||||
FILE STATUS sedol-file-status.
|
||||
|
||||
DATA DIVISION.
|
||||
FILE SECTION.
|
||||
FD sedol-file.
|
||||
01 sedol PIC X(6).
|
||||
|
||||
WORKING-STORAGE SECTION.
|
||||
01 sedol-file-status PIC XX.
|
||||
88 sedol-file-ok VALUE "00".
|
||||
|
||||
01 digit-num PIC 9 COMP.
|
||||
|
||||
01 digit-weights-area VALUE "1317391".
|
||||
03 digit-weights PIC 9 OCCURS 7 TIMES.
|
||||
|
||||
01 weighted-sum-parts-area.
|
||||
03 weighted-sum-parts PIC 9(3) COMP OCCURS 6 TIMES.
|
||||
|
||||
01 weighted-sum PIC 9(3) COMP.
|
||||
|
||||
01 check-digit PIC 9.
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
OPEN INPUT sedol-file
|
||||
PERFORM UNTIL NOT sedol-file-ok
|
||||
READ sedol-file
|
||||
AT END
|
||||
EXIT PERFORM
|
||||
END-READ
|
||||
|
||||
MOVE FUNCTION UPPER-CASE(sedol) TO sedol
|
||||
|
||||
PERFORM VARYING digit-num FROM 1 BY 1 UNTIL digit-num > 6
|
||||
EVALUATE TRUE
|
||||
WHEN sedol (digit-num:1) IS ALPHABETIC-UPPER
|
||||
IF sedol (digit-num:1) = "A" OR "E" OR "I" OR "O" OR "U"
|
||||
DISPLAY "Invalid SEDOL: " sedol
|
||||
EXIT PERFORM CYCLE
|
||||
END-IF
|
||||
|
||||
COMPUTE weighted-sum-parts (digit-num) =
|
||||
(FUNCTION ORD(sedol (digit-num:1)) - FUNCTION ORD("A")
|
||||
+ 10) * digit-weights (digit-num)
|
||||
|
||||
WHEN sedol (digit-num:1) IS NUMERIC
|
||||
MULTIPLY FUNCTION NUMVAL(sedol (digit-num:1))
|
||||
BY digit-weights (digit-num)
|
||||
GIVING weighted-sum-parts (digit-num)
|
||||
|
||||
WHEN OTHER
|
||||
DISPLAY "Invalid SEDOL: " sedol
|
||||
EXIT PERFORM CYCLE
|
||||
END-EVALUATE
|
||||
END-PERFORM
|
||||
|
||||
INITIALIZE weighted-sum
|
||||
PERFORM VARYING digit-num FROM 1 BY 1 UNTIL digit-num > 6
|
||||
ADD weighted-sum-parts (digit-num) TO weighted-sum
|
||||
END-PERFORM
|
||||
|
||||
COMPUTE check-digit =
|
||||
FUNCTION MOD(10 - FUNCTION MOD(weighted-sum, 10), 10)
|
||||
|
||||
DISPLAY sedol check-digit
|
||||
END-PERFORM
|
||||
|
||||
CLOSE sedol-file
|
||||
.
|
||||
END PROGRAM sedol.
|
||||
6
Task/SEDOLs/Clojure/sedols.clj
Normal file
6
Task/SEDOLs/Clojure/sedols.clj
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
(defn sedols [xs]
|
||||
(letfn [(sedol [ys] (let [weights [1 3 1 7 3 9]
|
||||
convtonum (map #(Character/getNumericValue %) ys)
|
||||
check (-> (reduce + (map * weights convtonum)) (rem 10) (->> (- 10)) (rem 10))]
|
||||
(str ys check)))]
|
||||
(map #(sedol %) xs)))
|
||||
12
Task/SEDOLs/Common-Lisp/sedols.lisp
Normal file
12
Task/SEDOLs/Common-Lisp/sedols.lisp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
(defun append-sedol-check-digit (sedol &key (start 0) (end (+ start 6)))
|
||||
(assert (<= 0 start end (length sedol)))
|
||||
(assert (= (- end start) 6))
|
||||
(loop
|
||||
:with checksum = 0
|
||||
:for weight :in '(1 3 1 7 3 9)
|
||||
:for index :upfrom start
|
||||
:do (incf checksum (* weight (digit-char-p (char sedol index) 36)))
|
||||
:finally (let* ((posn (- 10 (mod checksum 10)))
|
||||
(head (subseq sedol start end))
|
||||
(tail (digit-char posn)))
|
||||
(return (concatenate 'string head (list tail))))))
|
||||
20
Task/SEDOLs/D/sedols-1.d
Normal file
20
Task/SEDOLs/D/sedols-1.d
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import std.stdio, std.algorithm, std.string, std.numeric, std.ascii;
|
||||
|
||||
char checksum(in char[] sedol) pure @safe /*@nogc*/
|
||||
in {
|
||||
assert(sedol.length == 6);
|
||||
foreach (immutable c; sedol)
|
||||
assert(c.isDigit || (c.isUpper && !"AEIOU".canFind(c)));
|
||||
} out (result) {
|
||||
assert(result.isDigit);
|
||||
} body {
|
||||
static immutable c2v = (in dchar c) => c.isDigit ? c - '0' : (c - 'A' + 10);
|
||||
immutable int d = sedol.map!c2v.dotProduct([1, 3, 1, 7, 3, 9]);
|
||||
return digits[10 - (d % 10)];
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (const sedol; "710889 B0YBKJ 406566 B0YBLH 228276
|
||||
B0YBKL 557910 B0YBKR 585284 B0YBKT".split)
|
||||
writeln(sedol, sedol.checksum);
|
||||
}
|
||||
38
Task/SEDOLs/D/sedols-2.d
Normal file
38
Task/SEDOLs/D/sedols-2.d
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import std.stdio, std.algorithm, std.string, std.numeric, std.ascii;
|
||||
|
||||
char sedolChecksum(in char[] sedol) pure nothrow @safe /*@nogc*/
|
||||
in {
|
||||
assert(sedol.length == 6, "SEDOL must be 6 chars long.");
|
||||
enum uint mask = 0b11_1110_1111_1011_1110_1110_1110;
|
||||
|
||||
foreach (immutable c; sedol)
|
||||
assert(c.isDigit ||
|
||||
(c > 'A' && c <= 'Z' && ((1U << (c - 'A')) & mask)),
|
||||
"SEDOL with wrong char.");
|
||||
} out(result) {
|
||||
assert(result.isDigit);
|
||||
static int c2v(in dchar c) pure nothrow @safe @nogc {
|
||||
return c.isDigit ? c - '0' : c - 'A' + 10;
|
||||
}
|
||||
immutable int d = sedol.map!c2v.dotProduct([1, 3, 1, 7, 3, 9]);
|
||||
assert((d + result - '0') % 10 == 0);
|
||||
} body {
|
||||
static immutable int[] weights = [1, 3, 1, 7, 3, 9];
|
||||
|
||||
int sum = 0;
|
||||
foreach (immutable i, immutable c; sedol) {
|
||||
if (c.isDigit)
|
||||
sum += (c - '0') * weights[i];
|
||||
else
|
||||
sum += (c - 'A' + 10) * weights[i];
|
||||
}
|
||||
|
||||
return '0' + 10 - (sum % 10);
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (immutable s; ["710889", "B0YBKJ", "406566", "B0YBLH",
|
||||
"228276", "B0YBKL", "557910", "B0YBKR",
|
||||
"585284", "B0YBKT"])
|
||||
writeln(s, s.sedolChecksum);
|
||||
}
|
||||
9
Task/SEDOLs/D/sedols-3.d
Normal file
9
Task/SEDOLs/D/sedols-3.d
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
void main() {
|
||||
import std.stdio, std.algorithm, std.string, std.numeric,std.ascii;
|
||||
|
||||
foreach (const s; "710889 B0YBKJ 406566 B0YBLH 228276
|
||||
B0YBKL 557910 B0YBKR 585284 B0YBKT".split)
|
||||
writeln(s, '0' + 10 - s
|
||||
.map!(c => c.isDigit ? c - '0' : c - 'A' + 10)
|
||||
.dotProduct([1, 3, 1, 7, 3, 9]) % 10);
|
||||
}
|
||||
79
Task/SEDOLs/Delphi/sedols.delphi
Normal file
79
Task/SEDOLs/Delphi/sedols.delphi
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
program Sedol;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
uses
|
||||
SysUtils;
|
||||
|
||||
|
||||
const
|
||||
SEDOL_CHR_COUNT = 6;
|
||||
DIGITS = ['0'..'9'];
|
||||
LETTERS = ['A'..'Z'];
|
||||
VOWELS = ['A', 'E', 'I', 'O', 'U'];
|
||||
ACCEPTABLE_CHRS = DIGITS + LETTERS - VOWELS;
|
||||
WEIGHTS : ARRAY [1..SEDOL_CHR_COUNT] of integer = (1, 3, 1, 7, 3, 9);
|
||||
LETTER_OFFSET = 9;
|
||||
|
||||
|
||||
function AddSedolCheckDigit(Sedol : string) : string;
|
||||
var
|
||||
iChr : integer;
|
||||
Checksum : integer;
|
||||
CheckDigit : char;
|
||||
begin
|
||||
if Sedol <> uppercase(Sedol) then
|
||||
raise ERangeError.CreateFmt('%s contains lower case characters',[Sedol]);
|
||||
if length(Sedol) <> SEDOL_CHR_COUNT then
|
||||
raise ERangeError.CreateFmt('"%s" length is invalid. Should be 6 characters',[Sedol]);
|
||||
|
||||
Checksum := 0;
|
||||
for iChr := 1 to SEDOL_CHR_COUNT do
|
||||
begin
|
||||
|
||||
if Sedol[iChr] in Vowels then
|
||||
raise ERangeError.CreateFmt('%s contains a vowel (%s) at chr %d',[Sedol, Sedol[iChr], iChr]);
|
||||
if not (Sedol[iChr] in ACCEPTABLE_CHRS) then
|
||||
raise ERangeError.CreateFmt('%s contains an invalid chr (%s) at position %d',[Sedol, Sedol[iChr], iChr]);
|
||||
|
||||
if Sedol[iChr] in DIGITS then
|
||||
Checksum := Checksum + (ord(Sedol[iChr]) - ord('0')) * WEIGHTS[iChr]
|
||||
else
|
||||
Checksum := Checksum + (ord(Sedol[iChr]) - ord('A') + 1 + LETTER_OFFSET) * WEIGHTS[iChr];
|
||||
|
||||
end;
|
||||
|
||||
Checksum := (Checksum mod 10);
|
||||
if Checksum <> 0 then
|
||||
Checksum := 10 - Checksum;
|
||||
CheckDigit := chr(CheckSum + ord('0'));
|
||||
|
||||
Result := Sedol + CheckDigit;
|
||||
end;
|
||||
|
||||
|
||||
procedure Test(First6 : string);
|
||||
begin
|
||||
writeln(First6, ' becomes ', AddSedolCheckDigit(First6));
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
try
|
||||
Test('710889');
|
||||
Test('B0YBKJ');
|
||||
Test('406566');
|
||||
Test('B0YBLH');
|
||||
Test('228276');
|
||||
Test('B0YBKL');
|
||||
Test('557910');
|
||||
Test('B0YBKR');
|
||||
Test('585284');
|
||||
Test('B0YBKT');
|
||||
Test('B00030');
|
||||
except
|
||||
on E : Exception do
|
||||
writeln(E.Message);
|
||||
end;
|
||||
readln;
|
||||
end.
|
||||
37
Task/SEDOLs/E/sedols.e
Normal file
37
Task/SEDOLs/E/sedols.e
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
def weights := [1,3,1,7,3,9]
|
||||
def Digit := ('0'..'9')
|
||||
def Letter := ('B'..'D'|'F'..'H'|'J'..'N'|'P'..'T'|'V'..'Z')
|
||||
def sedolCharValue(c) {
|
||||
switch (c) {
|
||||
match digit :Digit { return digit - '0' }
|
||||
match letter :Letter {
|
||||
return letter - 'A'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def checksum(sedol :String) {
|
||||
require(sedol.size() == 6)
|
||||
var sum := 0
|
||||
for i => c in sedol {
|
||||
sum += weights[i] * sedolCharValue(c)
|
||||
}
|
||||
return E.toString((10 - sum %% 10) %% 10)
|
||||
}
|
||||
|
||||
def addChecksum(sedol :String) {
|
||||
return sedol + checksum(sedol)
|
||||
}
|
||||
|
||||
for sedol in "710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT".trim().split("\n") {
|
||||
println(addChecksum(sedol.trim()))
|
||||
}
|
||||
43
Task/SEDOLs/Elixir/sedols.elixir
Normal file
43
Task/SEDOLs/Elixir/sedols.elixir
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
defmodule SEDOL do
|
||||
@sedol_char "0123456789BCDFGHJKLMNPQRSTVWXYZ" |> String.codepoints
|
||||
@sedolweight [1,3,1,7,3,9]
|
||||
|
||||
defp char2value(c) do
|
||||
unless c in @sedol_char, do: raise ArgumentError, "No vowels"
|
||||
String.to_integer(c,36)
|
||||
end
|
||||
|
||||
def checksum(sedol) do
|
||||
if String.length(sedol) != length(@sedolweight), do: raise ArgumentError, "Invalid length"
|
||||
sum = Enum.zip(String.codepoints(sedol), @sedolweight)
|
||||
|> Enum.map(fn {ch, weight} -> char2value(ch) * weight end)
|
||||
|> Enum.sum
|
||||
to_string(rem(10 - rem(sum, 10), 10))
|
||||
end
|
||||
end
|
||||
|
||||
data = ~w{
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030
|
||||
C0000
|
||||
1234567
|
||||
00000A
|
||||
}
|
||||
|
||||
Enum.each(data, fn sedol ->
|
||||
:io.fwrite "~-8s ", [sedol]
|
||||
try do
|
||||
IO.puts sedol <> SEDOL.checksum(sedol)
|
||||
rescue
|
||||
e in ArgumentError -> IO.inspect e
|
||||
end
|
||||
end)
|
||||
33
Task/SEDOLs/Excel/sedols-1.excel
Normal file
33
Task/SEDOLs/Excel/sedols-1.excel
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
SEDOLCHECKSUM
|
||||
=LAMBDA(s,
|
||||
IF(6 = LEN(s),
|
||||
LET(
|
||||
cs, MID(s, SEQUENCE(1, 6, 1, 1), 1),
|
||||
isVowel, LAMBDA(c,
|
||||
ELEM(c)({"A","E","I","O","U"})
|
||||
),
|
||||
sedolValue, LAMBDA(c,
|
||||
LET(
|
||||
ic, CODE(c),
|
||||
IF(65 > ic,
|
||||
ic - 48,
|
||||
(ic + 10) - 65
|
||||
)
|
||||
)
|
||||
),
|
||||
IF(OR(isVowel(cs)),
|
||||
" -> Invalid vowel in SEDOL string",
|
||||
MOD(
|
||||
10 - MOD(
|
||||
SUM(
|
||||
MUL({1,3,1,7,3,9})(
|
||||
sedolValue(cs)
|
||||
)
|
||||
), 10
|
||||
), 10
|
||||
)
|
||||
)
|
||||
),
|
||||
"Expected a 6-character SEDOL"
|
||||
)
|
||||
)
|
||||
10
Task/SEDOLs/Excel/sedols-2.excel
Normal file
10
Task/SEDOLs/Excel/sedols-2.excel
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
ELEM
|
||||
=LAMBDA(x,
|
||||
LAMBDA(xs,
|
||||
ISNUMBER(MATCH(x, xs, 0))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
MUL
|
||||
=LAMBDA(a, LAMBDA(b, a * b))
|
||||
28
Task/SEDOLs/F-Sharp/sedols.fs
Normal file
28
Task/SEDOLs/F-Sharp/sedols.fs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
open System
|
||||
let Inputs = ["710889"; "B0YBKJ"; "406566"; "B0YBLH"; "228276"; "B0YBKL"
|
||||
"557910"; "B0YBKR"; "585284"; "B0YBKT"; "B00030"]
|
||||
|
||||
let Vowels = set ['A'; 'E'; 'I'; 'O'; 'U']
|
||||
let Weights = [1; 3; 1; 7; 3; 9; 1]
|
||||
|
||||
let inline isVowel c = Vowels.Contains (Char.ToUpper c)
|
||||
|
||||
let char2value c =
|
||||
if Char.IsDigit c then int c - 0x30
|
||||
else (['A'..'Z'] |> List.findIndex ((=) (Char.ToUpper c))) + 10
|
||||
|
||||
let sedolCheckDigit (input: string) =
|
||||
if input.Length <> 6 || input |> Seq.exists isVowel then
|
||||
failwithf "Input must be six characters long and not contain vowels: %s" input
|
||||
|
||||
let sum = Seq.map2 (fun ch weight -> (char2value ch) * weight) input Weights |> Seq.sum
|
||||
(10 - sum%10)%10
|
||||
|
||||
let addCheckDigit inputs =
|
||||
inputs |> List.map (fun s -> s + (sedolCheckDigit s).ToString())
|
||||
|
||||
let processDigits() =
|
||||
try
|
||||
addCheckDigit Inputs |> List.iter (printfn "%s")
|
||||
with
|
||||
ex -> printfn "ERROR: %s" ex.Message
|
||||
42
Task/SEDOLs/Factor/sedols.factor
Normal file
42
Task/SEDOLs/Factor/sedols.factor
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
USING: combinators combinators.short-circuit formatting io kernel
|
||||
math math.parser regexp sequences unicode ;
|
||||
IN: rosetta-code.sedols
|
||||
|
||||
<PRIVATE
|
||||
|
||||
CONSTANT: input {
|
||||
"710889" "B0YBKJ" "406566" "B0YBLH" "228276" "B0YBKL"
|
||||
"557910" "B0YBKR" "585284" "B0YBKT" "B00030" "AEIOUA"
|
||||
"123" "" "B_7K90"
|
||||
}
|
||||
|
||||
CONSTANT: weights B{ 1 3 1 7 3 9 1 }
|
||||
|
||||
: sedol-error ( seq -- err-str )
|
||||
{
|
||||
{ [ dup empty? ] [ drop "no data" ] }
|
||||
{ [ dup length 6 = not ] [ drop "invalid length" ] }
|
||||
[ drop "invalid char(s)" ]
|
||||
} cond "*error* " prepend ;
|
||||
|
||||
: sedol-valid? ( seq -- ? )
|
||||
{ [ length 6 = ] [ R/ [0-9BCDFGHJ-NP-TV-Z]+/ matches? ] } 1&& ;
|
||||
|
||||
: sedol-value ( m -- n ) dup digit? [ digit> ] [ 55 - ] if ;
|
||||
|
||||
: sedol-checksum ( seq -- n )
|
||||
[ sedol-value ] { } map-as weights [ * ] 2map sum ;
|
||||
|
||||
: (sedol-check-digit) ( seq -- str )
|
||||
sedol-checksum 10 mod 10 swap - 10 mod number>string ;
|
||||
|
||||
PRIVATE>
|
||||
|
||||
: sedol-check-digit ( seq -- str )
|
||||
dup sedol-valid? [ (sedol-check-digit) ] [ sedol-error ] if ;
|
||||
|
||||
: sedol-demo ( -- )
|
||||
"SEDOL Check digit\n====== ===========" print
|
||||
input [ dup sedol-check-digit "%-6s %s\n" printf ] each ;
|
||||
|
||||
MAIN: sedol-demo
|
||||
28
Task/SEDOLs/Forth/sedols.fth
Normal file
28
Task/SEDOLs/Forth/sedols.fth
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
create weight 1 , 3 , 1 , 7 , 3 , 9 ,
|
||||
|
||||
: char>num ( '0-9A-Z' -- 0..35 )
|
||||
dup [char] 9 > 7 and - [char] 0 - ;
|
||||
|
||||
: check+ ( sedol -- sedol' )
|
||||
6 <> abort" wrong SEDOL length"
|
||||
0 ( sum )
|
||||
6 0 do
|
||||
over I + c@ char>num
|
||||
weight I cells + @ *
|
||||
+
|
||||
loop
|
||||
10 mod 10 swap - 10 mod [char] 0 +
|
||||
over 6 + c! 7 ;
|
||||
|
||||
: sedol" [char] " parse check+ type ;
|
||||
|
||||
sedol" 710889" 7108899 ok
|
||||
sedol" B0YBKJ" B0YBKJ7 ok
|
||||
sedol" 406566" 4065663 ok
|
||||
sedol" B0YBLH" B0YBLH2 ok
|
||||
sedol" 228276" 2282765 ok
|
||||
sedol" B0YBKL" B0YBKL9 ok
|
||||
sedol" 557910" 5579107 ok
|
||||
sedol" B0YBKR" B0YBKR5 ok
|
||||
sedol" 585284" 5852842 ok
|
||||
sedol" B0YBKT" B0YBKT7 ok
|
||||
43
Task/SEDOLs/Fortran/sedols.f
Normal file
43
Task/SEDOLs/Fortran/sedols.f
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
MODULE SEDOL_CHECK
|
||||
IMPLICIT NONE
|
||||
CONTAINS
|
||||
|
||||
FUNCTION Checkdigit(c)
|
||||
CHARACTER :: Checkdigit
|
||||
CHARACTER(6), INTENT(IN) :: c
|
||||
CHARACTER(36) :: alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
INTEGER, DIMENSION(6) :: weights = (/ 1, 3, 1, 7, 3, 9 /), temp
|
||||
INTEGER :: i, n
|
||||
|
||||
DO i = 1, 6
|
||||
temp(i) = INDEX(alpha, c(i:i)) - 1
|
||||
END DO
|
||||
temp = temp * weights
|
||||
n = MOD(10 - (MOD(SUM(temp), 10)), 10)
|
||||
Checkdigit = ACHAR(n + 48)
|
||||
END FUNCTION Checkdigit
|
||||
|
||||
END MODULE SEDOL_CHECK
|
||||
|
||||
PROGRAM SEDOLTEST
|
||||
USE SEDOL_CHECK
|
||||
IMPLICIT NONE
|
||||
|
||||
CHARACTER(31) :: valid = "0123456789BCDFGHJKLMNPQRSTVWXYZ"
|
||||
CHARACTER(6) :: codes(10) = (/ "710889", "B0YBKJ", "406566", "B0YBLH", "228276" , &
|
||||
"B0YBKL", "557910", "B0YBKR", "585284", "B0YBKT" /)
|
||||
CHARACTER(7) :: sedol
|
||||
INTEGER :: i, invalid
|
||||
|
||||
DO i = 1, 10
|
||||
invalid = VERIFY(codes(i), valid)
|
||||
IF (invalid == 0) THEN
|
||||
sedol = codes(i)
|
||||
sedol(7:7) = Checkdigit(codes(i))
|
||||
ELSE
|
||||
sedol = "INVALID"
|
||||
END IF
|
||||
WRITE(*, "(2A9)") codes(i), sedol
|
||||
END DO
|
||||
|
||||
END PROGRAM SEDOLTEST
|
||||
93
Task/SEDOLs/FreeBASIC/sedols.basic
Normal file
93
Task/SEDOLs/FreeBASIC/sedols.basic
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
' version 05-07-2015
|
||||
' compile with: fbc -s console
|
||||
|
||||
Function check_sedol(input_nr As String) As Integer
|
||||
input_nr = Trim(input_nr)
|
||||
Dim As Integer i, j, x, nr_begin, sum
|
||||
Dim As String ch, legal = "AEIOU0123456789BCDFGHJKLMNPQRSTVWXYZ"
|
||||
Dim As Integer weight(0 To ...) = { 1, 3, 1, 7, 3, 9, 1}
|
||||
|
||||
x = Len(input_nr)
|
||||
If x < 6 Or x > 7 Then
|
||||
Return -99 ' to long or to short
|
||||
End If
|
||||
|
||||
For i = 0 To 5
|
||||
ch = Chr(input_nr[i])
|
||||
j = InStr(legal,ch)
|
||||
If j < 6 Then
|
||||
Return -90+j ' not a legal char. or a vowel
|
||||
End If
|
||||
j = ch[0] - Asc("0")
|
||||
If j > 9 Then j = j + (Asc("0") + 10- Asc("A"))
|
||||
If i = 0 AndAlso j < 10 Then nr_begin = 1
|
||||
If nr_begin = 1 AndAlso i > 0 Then
|
||||
If j > 9 Then Return -97 ' first is number then all be numbers
|
||||
End If
|
||||
sum = sum + j * weight(i)
|
||||
Next
|
||||
sum= ((10 - (sum Mod 10)) Mod 10)
|
||||
If x = 7 Then
|
||||
j=input_nr[6] - Asc("0") ' checksum digit is only number
|
||||
If j = sum Then
|
||||
Return 100+sum ' correct
|
||||
Else
|
||||
Return -98 ' wrong
|
||||
End If
|
||||
End If
|
||||
|
||||
Return sum ' checksum digit
|
||||
|
||||
End Function
|
||||
|
||||
Sub sedol(in As String)
|
||||
|
||||
Dim As Integer checksum = check_sedol(in)
|
||||
Print(in);
|
||||
|
||||
Select Case checksum
|
||||
Case -99
|
||||
Print " Illegal SEDOL: wrong length"
|
||||
Case -98
|
||||
Print " Illegal SEDOL: checksum digits do not match"
|
||||
Case -97
|
||||
Print " Illegal SEDOL: starts with number, may only contain numbers"
|
||||
Case -90
|
||||
Print " Illegal SEDOL: illegal character"
|
||||
Case -89 To -85
|
||||
Print " Illegal SEDOL: No vowels allowed"
|
||||
Case Is > 99
|
||||
Print " Valid SEDOL: checksums match"
|
||||
Case Else
|
||||
Print " checksum calculated : ";in;Str(checksum)
|
||||
End Select
|
||||
|
||||
End Sub
|
||||
' ------=< MAIN >=------
|
||||
|
||||
Dim As Integer k,checksum
|
||||
Dim As String in(1 To ...) = {"710889", "B0YBKJ", "406566", "B0YBLH",_
|
||||
"228276", "B0YBKL", "557910", "B0YBKR",_
|
||||
"585284", "B0YBKT", "B00030"}
|
||||
|
||||
Print "Calculated checksum"
|
||||
For k = 1 To UBound(in) : sedol(in(k)) : Next
|
||||
|
||||
Print : Print "Check checksum"
|
||||
Dim As String in1(1 To ...) = {"7108899", "B0YBKJ7", "4065663", "B0YBLH2",_
|
||||
"2282765", "B0YBKL9","5579107", "B0YBKR5",_
|
||||
"5852842", "B0YBKT7", "B000300"}
|
||||
|
||||
For k = 1 To UBound(in1) : sedol(in1(k)) : Next
|
||||
|
||||
Print : Print "Error test"
|
||||
Dim As String errors(1 To ...) = {"12", "1234567890", "1B0000", "123 45",_
|
||||
"A00000", "B000301"}
|
||||
|
||||
For k = 1 To UBound(errors) : sedol(errors(k)) : Next
|
||||
|
||||
' empty keyboard buffer
|
||||
While Inkey <> "" : Wend
|
||||
Print : Print "hit any key to end program"
|
||||
Sleep
|
||||
End
|
||||
29
Task/SEDOLs/Gambas/sedols.gambas
Normal file
29
Task/SEDOLs/Gambas/sedols.gambas
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
Public Sub Main()
|
||||
Dim byWeight As Byte[] = [1, 3, 1, 7, 3, 9, 1]
|
||||
Dim byCount, byCompute As Byte
|
||||
Dim siTotal As Short
|
||||
Dim sWork As New String[]
|
||||
Dim sToProcess As String[] = ["710889", "B0YBKJ", "406566", "B0YBLH", "228276", "B0YBKL",
|
||||
"557910", "B0YBKR", "585284", "B0YBKT", "B00030"]
|
||||
|
||||
For byCompute = 0 To sToProcess.Max
|
||||
For byCount = 1 To 6
|
||||
If IsLetter(Mid(sToProcess[byCompute], byCount, 1)) Then
|
||||
sWork.Add(Str(Asc(Mid(sToProcess[byCompute], byCount, 1)) - 55) * byWeight[byCount - 1])
|
||||
Else
|
||||
sWork.Add(Val(Mid(sToProcess[byCompute], byCount, 1)) * byWeight[byCount - 1])
|
||||
End If
|
||||
Next
|
||||
|
||||
For byCount = 0 To 5
|
||||
siTotal += Val(sWork[byCount])
|
||||
Next
|
||||
|
||||
siTotal = (10 - (siTotal Mod 10)) Mod 10
|
||||
|
||||
Print sToProcess[byCompute] & " = " & sToProcess[byCompute] & siTotal
|
||||
sWork.Clear()
|
||||
siTotal = 0
|
||||
Next
|
||||
|
||||
End
|
||||
62
Task/SEDOLs/Go/sedols.go
Normal file
62
Task/SEDOLs/Go/sedols.go
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const input = `710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030
|
||||
|
||||
B
|
||||
B0003
|
||||
B000300
|
||||
A00030
|
||||
E00030
|
||||
I00030
|
||||
O00030
|
||||
U00030
|
||||
β00030
|
||||
β0003`
|
||||
|
||||
var weight = [...]int{1,3,1,7,3,9}
|
||||
|
||||
func csd(code string) string {
|
||||
switch len(code) {
|
||||
case 6:
|
||||
case 0:
|
||||
return "No data"
|
||||
default:
|
||||
return "Invalid length"
|
||||
}
|
||||
sum := 0
|
||||
for i, c := range code {
|
||||
n, err := strconv.ParseInt(string(c), 36, 0)
|
||||
if err != nil || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' {
|
||||
return "Invalid character"
|
||||
}
|
||||
sum += int(n)*weight[i]
|
||||
}
|
||||
return strconv.Itoa(9-(sum-1)%10)
|
||||
}
|
||||
|
||||
func main() {
|
||||
for _, s := range strings.Split(input, "\n") {
|
||||
d := csd(s)
|
||||
if len(d) > 1 {
|
||||
fmt.Printf(":%s: %s\n", s, d)
|
||||
} else {
|
||||
fmt.Println(s + d)
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Task/SEDOLs/Groovy/sedols-1.groovy
Normal file
10
Task/SEDOLs/Groovy/sedols-1.groovy
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
def checksum(text) {
|
||||
assert text.size() == 6 && !text.toUpperCase().find(/[AEIOU]+/) : "Invalid SEDOL text: $text"
|
||||
|
||||
def sum = 0
|
||||
(0..5).each { index ->
|
||||
sum += Character.digit(text.charAt(index), 36) * [1, 3, 1, 7, 3, 9][index]
|
||||
}
|
||||
text + (10 - (sum % 10)) % 10
|
||||
}
|
||||
String.metaClass.sedol = { this.&checksum(delegate) }
|
||||
6
Task/SEDOLs/Groovy/sedols-2.groovy
Normal file
6
Task/SEDOLs/Groovy/sedols-2.groovy
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[ '710889': '7108899', 'B0YBKJ': 'B0YBKJ7', '406566': '4065663', 'B0YBLH': 'B0YBLH2',
|
||||
'228276': '2282765', 'B0YBKL': 'B0YBKL9', '557910': '5579107', 'B0YBKR': 'B0YBKR5',
|
||||
'585284': '5852842', 'B0YBKT': 'B0YBKT7', 'B00030': 'B000300'].each { text, expected ->
|
||||
println "Checking $text -> $expected"
|
||||
assert expected == text.sedol()
|
||||
}
|
||||
49
Task/SEDOLs/Haskell/sedols.hs
Normal file
49
Task/SEDOLs/Haskell/sedols.hs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import Data.Char (isAsciiUpper, isDigit, ord)
|
||||
|
||||
-------------------------- SEDOLS ------------------------
|
||||
|
||||
checkSum :: String -> String
|
||||
checkSum x =
|
||||
case traverse sedolValue x of
|
||||
Right xs -> (show . checkSumFromSedolValues) xs
|
||||
Left annotated -> annotated
|
||||
|
||||
checkSumFromSedolValues :: [Int] -> Int
|
||||
checkSumFromSedolValues xs =
|
||||
rem
|
||||
( 10
|
||||
- rem
|
||||
( sum $
|
||||
zipWith
|
||||
(*)
|
||||
[1, 3, 1, 7, 3, 9]
|
||||
xs
|
||||
)
|
||||
10
|
||||
)
|
||||
10
|
||||
|
||||
sedolValue :: Char -> Either String Int
|
||||
sedolValue c
|
||||
| c `elem` "AEIOU" = Left " ← Unexpected vowel."
|
||||
| isDigit c = Right (ord c - ord '0')
|
||||
| isAsciiUpper c = Right (ord c - ord 'A' + 10)
|
||||
|
||||
--------------------------- TEST -------------------------
|
||||
main :: IO ()
|
||||
main =
|
||||
mapM_
|
||||
(putStrLn . ((<>) <*> checkSum))
|
||||
[ "710889",
|
||||
"B0YBKJ",
|
||||
"406566",
|
||||
"B0YBLH",
|
||||
"228276",
|
||||
"B0YBKL",
|
||||
"557910",
|
||||
"B0YBKR",
|
||||
"585284",
|
||||
"B0YBKT",
|
||||
"BOYBKT", -- Ill formed test case - illegal vowel.
|
||||
"B00030"
|
||||
]
|
||||
19
Task/SEDOLs/Icon/sedols.icon
Normal file
19
Task/SEDOLs/Icon/sedols.icon
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
procedure main()
|
||||
every write(sedol("710889"|"B0YBKJ"|"406566"|"B0YBLH"|"228276"|
|
||||
"B0YBKL"|"557910"|"B0YBKR"|"585284"|"B0YBKT"|"B00030"))
|
||||
end
|
||||
|
||||
procedure sedol(x) #: return the completed sedol with check digit
|
||||
static w,c
|
||||
initial {
|
||||
every (i := -1, c := table())[!(&digits||&ucase)] := i +:= 1 # map chars
|
||||
every c[!"AEIOU"] := &null # delete vowels
|
||||
w := [1,3,1,7,3,9] # weights
|
||||
}
|
||||
|
||||
if *(x := map(x,&lcase,&ucase)) = *w then { # match lengths
|
||||
every (t :=0, i := 1 to *x) do
|
||||
t +:= \c[x[i]]*w[i] | fail # accumulate weighted chars
|
||||
return x || (10 - (t%10)) % 10 # complete
|
||||
}
|
||||
end
|
||||
2
Task/SEDOLs/J/sedols-1.j
Normal file
2
Task/SEDOLs/J/sedols-1.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
sn =. '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
ac0 =: (, 10 | 1 3 1 7 3 9 +/@:* -)&.(sn i. |:)
|
||||
1
Task/SEDOLs/J/sedols-2.j
Normal file
1
Task/SEDOLs/J/sedols-2.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
ac1 =: (, 10 | (10 - 1 3 1 7 3 9) +/@:* ])&.(sn i. |:)
|
||||
1
Task/SEDOLs/J/sedols-3.j
Normal file
1
Task/SEDOLs/J/sedols-3.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
ac2 =: (, 10 | 9 7 9 3 7 1 +/@:* ])&.(sn i. |:)
|
||||
1
Task/SEDOLs/J/sedols-4.j
Normal file
1
Task/SEDOLs/J/sedols-4.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
ac3 =: (,"1 0 (841 $ '0987654321') {~ 1 3 1 7 3 9 +/ .*~ sn i. ])
|
||||
31
Task/SEDOLs/Java/sedols.java
Normal file
31
Task/SEDOLs/Java/sedols.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import java.util.Scanner;
|
||||
|
||||
public class SEDOL{
|
||||
public static void main(String[] args){
|
||||
Scanner sc = new Scanner(System.in);
|
||||
while(sc.hasNext()){
|
||||
String sedol = sc.next();
|
||||
System.out.println(sedol + getSedolCheckDigit(sedol));
|
||||
}
|
||||
}
|
||||
|
||||
private static final int[] mult = {1, 3, 1, 7, 3, 9};
|
||||
|
||||
public static int getSedolCheckDigit(String str){
|
||||
if(!validateSedol(str)){
|
||||
System.err.println("SEDOL strings must contain six characters with no vowels.");
|
||||
return -1;
|
||||
}
|
||||
str = str.toUpperCase();
|
||||
int total = 0;
|
||||
for(int i = 0;i < 6; i++){
|
||||
char s = str.charAt(i);
|
||||
total += Character.digit(s, 36) * mult[i];
|
||||
}
|
||||
return (10 - (total % 10)) % 10;
|
||||
}
|
||||
|
||||
public static boolean validateSedol(String str){
|
||||
return (str.length() == 6) && !str.toUpperCase().matches(".*?[AEIOU].*?");
|
||||
}
|
||||
}
|
||||
41
Task/SEDOLs/JavaScript/sedols-1.js
Normal file
41
Task/SEDOLs/JavaScript/sedols-1.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
function sedol(input) {
|
||||
return input + sedol_check_digit(input);
|
||||
}
|
||||
|
||||
var weight = [1, 3, 1, 7, 3, 9, 1];
|
||||
function sedol_check_digit(char6) {
|
||||
if (char6.search(/^[0-9BCDFGHJKLMNPQRSTVWXYZ]{6}$/) == -1)
|
||||
throw "Invalid SEDOL number '" + char6 + "'";
|
||||
var sum = 0;
|
||||
for (var i = 0; i < char6.length; i++)
|
||||
sum += weight[i] * parseInt(char6.charAt(i), 36);
|
||||
var check = (10 - sum%10) % 10;
|
||||
return check.toString();
|
||||
}
|
||||
|
||||
var input = [
|
||||
'710889', 'B0YBKJ', '406566', 'B0YBLH', '228276',
|
||||
'B0YBKL', '557910', 'B0YBKR', '585284', 'B0YBKT',
|
||||
"BOATER" , "12345", "123456", "1234567"
|
||||
];
|
||||
|
||||
var expected = [
|
||||
'7108899', 'B0YBKJ7', '4065663', 'B0YBLH2', '2282765',
|
||||
'B0YBKL9', '5579107', 'B0YBKR5', '5852842', 'B0YBKT7',
|
||||
null, null, '1234563', null
|
||||
];
|
||||
|
||||
for (var i in input) {
|
||||
try {
|
||||
var sedolized = sedol(input[i]);
|
||||
if (sedolized == expected[i])
|
||||
print(sedolized);
|
||||
else
|
||||
print("error: calculated sedol for input " + input[i] +
|
||||
" is " + sedolized + ", but it should be " + expected[i]
|
||||
);
|
||||
}
|
||||
catch (e) {
|
||||
print("error: " + e);
|
||||
}
|
||||
}
|
||||
164
Task/SEDOLs/JavaScript/sedols-2.js
Normal file
164
Task/SEDOLs/JavaScript/sedols-2.js
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
const main = () => {
|
||||
|
||||
// checkSumLR :: String -> Either String String
|
||||
const checkSumLR = s => {
|
||||
const
|
||||
tpl = partitionEithers(map(charValueLR, s));
|
||||
return 0 < tpl[0].length ? (
|
||||
Left(s + ' -> ' + unwords(tpl[0]))
|
||||
) : Right(rem(10 - rem(
|
||||
sum(zipWith(
|
||||
(a, b) => a * b,
|
||||
[1, 3, 1, 7, 3, 9],
|
||||
tpl[1]
|
||||
)), 10
|
||||
), 10).toString());
|
||||
};
|
||||
|
||||
// charValue :: Char -> Either String Int
|
||||
const charValueLR = c =>
|
||||
isAlpha(c) ? (
|
||||
isUpper(c) ? (
|
||||
elem(c, 'AEIOU') ? Left(
|
||||
'Unexpected vowel: ' + c
|
||||
) : Right(ord(c) - ord('A') + 10)
|
||||
) : Left('Unexpected lower case character: ' + c)
|
||||
) : isDigit(c) ? Right(
|
||||
parseInt(c, 10)
|
||||
) : Left('Unexpected character: ' + c);
|
||||
|
||||
// TESTS ------------------------------------------
|
||||
const [problems, checks] = Array.from(
|
||||
partitionEithers(map(s => bindLR(
|
||||
checkSumLR(s),
|
||||
c => Right(s + c)
|
||||
),
|
||||
[
|
||||
"710889", "B0YBKJ", "406566",
|
||||
"B0YBLH", "228276", "B0YBKL",
|
||||
"557910", "B0YBKR", "585284",
|
||||
"B0YBKT", "B00030"
|
||||
]
|
||||
))
|
||||
);
|
||||
return unlines(
|
||||
0 < problems.length ? (
|
||||
problems
|
||||
) : checks
|
||||
);
|
||||
};
|
||||
|
||||
// GENERIC FUNCTIONS ----------------------------
|
||||
|
||||
// Left :: a -> Either a b
|
||||
const Left = x => ({
|
||||
type: 'Either',
|
||||
Left: x
|
||||
});
|
||||
|
||||
// Right :: b -> Either a b
|
||||
const Right = x => ({
|
||||
type: 'Either',
|
||||
Right: x
|
||||
});
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = (a, b) => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
// bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
|
||||
const bindLR = (m, mf) =>
|
||||
undefined !== m.Left ? (
|
||||
m
|
||||
) : mf(m.Right);
|
||||
|
||||
// elem :: Eq a => a -> [a] -> Bool
|
||||
const elem = (x, xs) => xs.includes(x);
|
||||
|
||||
// isAlpha :: Char -> Bool
|
||||
const isAlpha = c =>
|
||||
/[A-Za-z\u00C0-\u00FF]/.test(c);
|
||||
|
||||
// isDigit :: Char -> Bool
|
||||
const isDigit = c => {
|
||||
const n = ord(c);
|
||||
return 48 <= n && 57 >= n;
|
||||
};
|
||||
|
||||
// isUpper :: Char -> Bool
|
||||
const isUpper = c =>
|
||||
/[A-Z]/.test(c);
|
||||
|
||||
// Returns Infinity over objects without finite length.
|
||||
// This enables zip and zipWith to choose the shorter
|
||||
// argument when one is non-finite, like cycle, repeat etc
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs =>
|
||||
(Array.isArray(xs) || 'string' === typeof xs) ? (
|
||||
xs.length
|
||||
) : Infinity;
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) =>
|
||||
(Array.isArray(xs) ? (
|
||||
xs
|
||||
) : xs.split('')).map(f);
|
||||
|
||||
// ord :: Char -> Int
|
||||
const ord = c => c.codePointAt(0);
|
||||
|
||||
// partitionEithers :: [Either a b] -> ([a],[b])
|
||||
const partitionEithers = xs =>
|
||||
xs.reduce(
|
||||
(a, x) => undefined !== x.Left ? (
|
||||
Tuple(a[0].concat(x.Left), a[1])
|
||||
) : Tuple(a[0], a[1].concat(x.Right)),
|
||||
Tuple([], [])
|
||||
);
|
||||
|
||||
// rem :: Int -> Int -> Int
|
||||
const rem = (n, m) => n % m;
|
||||
|
||||
// sum :: [Num] -> Num
|
||||
const sum = xs => xs.reduce((a, x) => a + x, 0);
|
||||
|
||||
// take :: Int -> [a] -> [a]
|
||||
// take :: Int -> String -> String
|
||||
const take = (n, xs) =>
|
||||
'GeneratorFunction' !== xs.constructor.constructor.name ? (
|
||||
xs.slice(0, n)
|
||||
) : [].concat.apply([], Array.from({
|
||||
length: n
|
||||
}, () => {
|
||||
const x = xs.next();
|
||||
return x.done ? [] : [x.value];
|
||||
}));
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// unwords :: [String] -> String
|
||||
const unwords = xs => xs.join(' ');
|
||||
|
||||
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
const zipWith = (f, xs, ys) => {
|
||||
const
|
||||
lng = Math.min(length(xs), length(ys)),
|
||||
as = take(lng, xs),
|
||||
bs = take(lng, ys);
|
||||
return Array.from({
|
||||
length: lng
|
||||
}, (_, i) => f(as[i], bs[i], i));
|
||||
};
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
43
Task/SEDOLs/Jq/sedols.jq
Normal file
43
Task/SEDOLs/Jq/sedols.jq
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
def ascii_upcase:
|
||||
explode | map( if 97 <= . and . <= 122 then . - 32 else . end) | implode;
|
||||
|
||||
def sedol_checksum:
|
||||
def encode(a): 10 + (a|explode[0]) - ("A"|explode[0]);
|
||||
. as $sed
|
||||
| [1,3,1,7,3,9] as $sw
|
||||
| reduce range(0;6) as $i
|
||||
(0;
|
||||
$sed[$i:$i+1] as $c
|
||||
| if ( "0123456789" | index($c) )
|
||||
then . + ($c|tonumber) * $sw[$i]
|
||||
else . + encode($c) * $sw[$i]
|
||||
end )
|
||||
| (10 - (. % 10)) % 10 ;
|
||||
|
||||
# error on error, else pass input to output
|
||||
def check_valid_sedol:
|
||||
def has_vowel:
|
||||
("AEIOU"|explode) as $vowels
|
||||
| reduce explode[] as $c
|
||||
(false; if . then . else $vowels|index($c) end);
|
||||
|
||||
if has_vowel then error( "\(.) is not a valid SEDOL code" )
|
||||
else .
|
||||
end
|
||||
| if length > 7 or length < 6 then
|
||||
error( "\(.) is too long or too short to be valid SEDOL")
|
||||
else .
|
||||
end;
|
||||
|
||||
def sedolize:
|
||||
ascii_upcase as $in
|
||||
| $in
|
||||
| check_valid_sedol
|
||||
| .[0:6] as $sedol
|
||||
| ($sedol | sedol_checksum | tostring) as $sedolcheck
|
||||
| ($sedol + $sedolcheck) as $ans
|
||||
| if length == 7 and $ans != $in then
|
||||
$ans + " (original \($in) has wrong checksum digit"
|
||||
else $ans
|
||||
end ;
|
||||
sedolize
|
||||
21
Task/SEDOLs/Julia/sedols.julia
Normal file
21
Task/SEDOLs/Julia/sedols.julia
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using Base.Test
|
||||
|
||||
function appendchecksum(chars::AbstractString)
|
||||
if !all(isalnum, chars) throw(ArgumentError("invalid SEDOL number '$chars'")) end
|
||||
weights = [1, 3, 1, 7, 3, 9, 1]
|
||||
|
||||
s = 0
|
||||
for (w, c) in zip(weights, chars)
|
||||
s += w * parse(Int, c, 36)
|
||||
end
|
||||
return string(chars, (10 - s % 10) % 10)
|
||||
end
|
||||
|
||||
tests = ["710889", "B0YBKJ", "406566", "B0YBLH", "228276", "B0YBKL", "557910", "B0YBKR", "585284", "B0YBKT", "B00030"]
|
||||
csums = ["7108899", "B0YBKJ7", "4065663", "B0YBLH2", "2282765", "B0YBKL9", "5579107", "B0YBKR5", "5852842", "B0YBKT7", "B000300"]
|
||||
|
||||
@testset "Checksums" begin
|
||||
for (t, c) in zip(tests, csums)
|
||||
@test appendchecksum(t) == c
|
||||
end
|
||||
end
|
||||
25
Task/SEDOLs/Kotlin/sedols.kotlin
Normal file
25
Task/SEDOLs/Kotlin/sedols.kotlin
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// version 1.1.0
|
||||
|
||||
val weights = listOf(1, 3, 1, 7, 3, 9, 1)
|
||||
|
||||
fun sedol7(sedol6: String): String {
|
||||
if (sedol6.length != 6) throw IllegalArgumentException("Length of argument string must be 6")
|
||||
var sum = 0
|
||||
for (i in 0..5) {
|
||||
val c = sedol6[i]
|
||||
val v = when (c) {
|
||||
in '0'..'9' -> c.toInt() - 48
|
||||
in 'A'..'Z' -> c.toInt() - 55
|
||||
else -> throw IllegalArgumentException("Argument string contains an invalid character")
|
||||
}
|
||||
sum += v * weights[i]
|
||||
}
|
||||
val check = (10 - (sum % 10)) % 10
|
||||
return sedol6 + (check + 48).toChar()
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val sedol6s = listOf("710889", "B0YBKJ", "406566", "B0YBLH", "228276", "B0YBKL",
|
||||
"557910", "B0YBKR", "585284", "B0YBKT", "B00030")
|
||||
for (sedol6 in sedol6s) println("$sedol6 -> ${sedol7(sedol6)}")
|
||||
}
|
||||
58
Task/SEDOLs/Langur/sedols.langur
Normal file
58
Task/SEDOLs/Langur/sedols.langur
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
val .csd = f(.code) {
|
||||
given len(.code) {
|
||||
case 0:
|
||||
return "nada, zip, zilch"
|
||||
case != 6:
|
||||
return "invalid length"
|
||||
}
|
||||
|
||||
if matching(re/[^B-DF-HJ-NP-TV-Z0-9]/, .code) {
|
||||
return "invalid character(s)"
|
||||
}
|
||||
|
||||
val .weight = [1,3,1,7,3,9]
|
||||
|
||||
val .nums = s2n .code
|
||||
val .sum = for[=0] .i of .nums {
|
||||
_for += .nums[.i] x .weight[.i]
|
||||
}
|
||||
|
||||
toString 9 - (.sum - 1) rem 10
|
||||
}
|
||||
|
||||
val .h = h{
|
||||
# invalid...
|
||||
"": 0,
|
||||
"123": 0,
|
||||
"A00030": 0,
|
||||
"E00030": 0,
|
||||
"I00030": 0,
|
||||
"O00030": 0,
|
||||
"U00030": 0,
|
||||
"β00030": 0,
|
||||
|
||||
# valid...
|
||||
"710889": 9,
|
||||
"B0YBKJ": 7,
|
||||
"406566": 3,
|
||||
"B0YBLH": 2,
|
||||
"228276": 5,
|
||||
"B0YBKL": 9,
|
||||
"557910": 7,
|
||||
"B0YBKR": 5,
|
||||
"585284": 2,
|
||||
"B0YBKT": 7,
|
||||
"B00030": 0,
|
||||
}
|
||||
|
||||
for .input in sort(keys .h) {
|
||||
val .d = .csd(.input)
|
||||
if len(.d) > 1 {
|
||||
writeln .input, ": ", .d
|
||||
} else {
|
||||
val .expect = toString .h[.input]
|
||||
write .input, .d
|
||||
writeln if .expect == .d {""} else {
|
||||
$" (SEDOL test failed; expected check digit \.expect;)"}
|
||||
}
|
||||
}
|
||||
31
Task/SEDOLs/Liberty-BASIC/sedols.basic
Normal file
31
Task/SEDOLs/Liberty-BASIC/sedols.basic
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
'adapted from BASIC solution
|
||||
mult(1) = 1: mult(2) = 3: mult(3) = 1
|
||||
mult(4) = 7: mult(5) = 3: mult(6) = 9
|
||||
|
||||
DO
|
||||
INPUT a$
|
||||
PRINT a$ + STR$(getSedolCheckDigit(a$))
|
||||
LOOP WHILE a$ <> ""
|
||||
|
||||
FUNCTION getSedolCheckDigit (str$)
|
||||
IF LEN(str$) <> 6 THEN
|
||||
PRINT "Six chars only please"
|
||||
EXIT FUNCTION
|
||||
END IF
|
||||
str$ = upper$(str$)
|
||||
total = 0
|
||||
FOR i = 1 TO 6
|
||||
s$ = MID$(str$, i, 1)
|
||||
IF (s$ = "A") OR (s$ = "E") OR (s$ = "I") OR (s$ = "O") OR (s$ = "U") THEN
|
||||
PRINT "No vowels"
|
||||
EXIT FUNCTION
|
||||
END IF
|
||||
IF (ASC(s$) >= 48) AND (ASC(s$) <= 57) THEN
|
||||
total = total + VAL(s$) * mult(i)
|
||||
ELSE
|
||||
total = total + (ASC(s$) - 55) * mult(i)
|
||||
END IF
|
||||
|
||||
NEXT i
|
||||
getSedolCheckDigit = (10 - (total MOD 10)) MOD 10
|
||||
END FUNCTION
|
||||
17
Task/SEDOLs/M4/sedols.m4
Normal file
17
Task/SEDOLs/M4/sedols.m4
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
divert(-1)
|
||||
changequote(`[',`]')
|
||||
define([_bar],include(sedol.inp))
|
||||
define([eachlineA],
|
||||
[ifelse(eval($2>0),1,
|
||||
[$3(substr([$1],0,$2))[]eachline(substr([$1],incr($2)),[$3])])])
|
||||
define([eachline],[eachlineA([$1],index($1,[
|
||||
]),[$2])])
|
||||
define([_idx],
|
||||
[index([0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ],substr($1,$2,1))])
|
||||
define([_wsum],
|
||||
[eval(_idx($1,0)+_idx($1,1)*3+_idx($1,2)+_idx($1,3)*7+_idx($1,4)*3+_idx($1,5)*9)])
|
||||
define([checksum],
|
||||
[$1[]eval((10-_wsum($1)%10)%10)
|
||||
])
|
||||
divert
|
||||
eachline(_bar,[checksum])
|
||||
21
Task/SEDOLs/MUMPS/sedols.mumps
Normal file
21
Task/SEDOLs/MUMPS/sedols.mumps
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
SEDOL
|
||||
NEW A,B
|
||||
SEDOL1
|
||||
READ !,"Enter the first 6 digits of a SEDOL: ",A
|
||||
SET B=$$SEDOLCHK(A)
|
||||
WRITE !,$SELECT($LENGTH(B)=1:"Full SEDOL is "_A_B,1:B)
|
||||
GOTO SEDOL1
|
||||
QUIT
|
||||
SEDOLCHK(STOCK)
|
||||
NEW WT,VAL,I,CHK,C,FLAG
|
||||
SET WT="1317391",VAL=0,FLAG=0
|
||||
FOR I=1:1:6 SET C=$$TOUPPER($EXTRACT(STOCK,I)),VAL=VAL+($$SEDVAL(C)*$EXTRACT(WT,I)) SET:"AEIOUaeiou"[C FLAG=1
|
||||
SET:$LENGTH(STOCK)'=6 FLAG=1
|
||||
KILL WT,I,CHK,C
|
||||
QUIT $SELECT(FLAG:"INVALID",'FLAG:(10-(VAL#10))#10)
|
||||
SEDVAL(X)
|
||||
QUIT $SELECT($ISVALIDNUM(X):X,1:$ASCII(X)-$ASCII("@")+9)
|
||||
TOUPPER(X)
|
||||
NEW UP,LO
|
||||
SET UP="ABCDEFGHIJKLMNOPQRSTUVWXYZ",LO="abcdefghijklmnopqrstuvwxyz"
|
||||
QUIT $TRANSLATE(X,LO,UP)
|
||||
4
Task/SEDOLs/Mathematica/sedols.math
Normal file
4
Task/SEDOLs/Mathematica/sedols.math
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
SEDOL[Code_?(Function[v,StringFreeQ[v,{"A","E","I","O","U"}]])]:=
|
||||
Code<>ToString[10-Mod[ToExpression[Quiet[Flatten[Characters[Code]
|
||||
/.x_?LetterQ->(ToCharacterCode[x]-55)]]].{1,3,1,7,3,9},10]]
|
||||
Scan[Print[SEDOL[#]] &, {"710889","B0YBKJ","406566","B0YBLH","228276","B0YBKL","557910","B0YBKR","585284","B0YBKT","B00030","DUMMY"}]
|
||||
53
Task/SEDOLs/Mercury/sedols.mercury
Normal file
53
Task/SEDOLs/Mercury/sedols.mercury
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
:- module sedol.
|
||||
:- interface.
|
||||
|
||||
:- import_module io.
|
||||
:- pred main(io::di, io::uo) is det.
|
||||
|
||||
:- implementation.
|
||||
:- import_module char, int, list, require, string.
|
||||
|
||||
main(!IO) :-
|
||||
Input = [
|
||||
"710889",
|
||||
"B0YBKJ",
|
||||
"406566",
|
||||
"B0YBLH",
|
||||
"228276",
|
||||
"B0YBKL",
|
||||
"557910",
|
||||
"B0YBKR",
|
||||
"585284",
|
||||
"B0YBKT",
|
||||
"B00030"
|
||||
],
|
||||
list.foldl(print_with_checksum, Input, !IO).
|
||||
|
||||
:- pred print_with_checksum(string::in, io::di, io::uo) is det.
|
||||
|
||||
print_with_checksum(S, !IO) :-
|
||||
io.format("%s%d\n", [s(S), i(sedol_checksum(S))], !IO).
|
||||
|
||||
:- func sedol_checksum(string) = int.
|
||||
|
||||
sedol_checksum(Sedol) = CheckSum :-
|
||||
Digits = string.foldr((func(C, A) = [to_sedol_code(C) | A]), Sedol, []),
|
||||
WeightedDigits = list.map_corresponding(int.times, Digits, [1, 3, 1, 7, 3, 9]),
|
||||
WeightedSum = list.foldl(int.plus, WeightedDigits, 0),
|
||||
CheckSum = (10 - (WeightedSum mod 10)) mod 10.
|
||||
|
||||
:- func to_sedol_code(char) = int.
|
||||
|
||||
to_sedol_code(Char) =
|
||||
( if char.digit_to_int(Char, Code), not is_vowel(to_upper(Char))
|
||||
then Code
|
||||
else func_error("invalid SEDOL")
|
||||
).
|
||||
|
||||
:- pred is_vowel(char::in) is semidet.
|
||||
|
||||
is_vowel('A').
|
||||
is_vowel('E').
|
||||
is_vowel('I').
|
||||
is_vowel('O').
|
||||
is_vowel('U').
|
||||
44
Task/SEDOLs/Modula-3/sedols.mod3
Normal file
44
Task/SEDOLs/Modula-3/sedols.mod3
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
MODULE SEDOL EXPORTS Main;
|
||||
|
||||
IMPORT IO, Fmt, Text, Stdio;
|
||||
|
||||
EXCEPTION BadSedol(TEXT);
|
||||
|
||||
VAR test := ARRAY [1..10] OF TEXT {"710889", "B0YBKJ", "406566", "B0YBLH",
|
||||
"228276", "B0YBKL", "557910", "B0YBKR",
|
||||
"585284", "B0YBKT" };
|
||||
|
||||
PROCEDURE Check(sed: TEXT): INTEGER RAISES {BadSedol}=
|
||||
VAR
|
||||
weights := ARRAY [0..5] OF INTEGER {1, 3, 1, 7, 3, 9};
|
||||
result, d: INTEGER;
|
||||
char: CHAR;
|
||||
BEGIN
|
||||
IF Text.Length(sed) # 6 THEN
|
||||
RAISE BadSedol("ERROR: Must be 6 digits.");
|
||||
END;
|
||||
result := 0;
|
||||
FOR i := 0 TO 5 DO
|
||||
char := Text.GetChar(sed, i);
|
||||
CASE char OF
|
||||
| '0'..'9' => d := ORD(char) - ORD('0');
|
||||
| 'B'..'D', 'F'..'H', 'J'..'N', 'P'..'T', 'V'..'Z'
|
||||
=> d := ORD(char) - ORD('A') + 10;
|
||||
ELSE
|
||||
RAISE BadSedol("ERROR: Must be numbers or (non-vowel) letters.");
|
||||
END;
|
||||
INC(result, d * weights[i]);
|
||||
END;
|
||||
result := (10 - (result MOD 10)) MOD 10;
|
||||
RETURN result;
|
||||
END Check;
|
||||
|
||||
BEGIN
|
||||
TRY
|
||||
FOR i := FIRST(test) TO LAST(test) DO
|
||||
IO.Put(test[i] & Fmt.Char(VAL(ORD('0') + Check(test[i]), CHAR)) & "\n");
|
||||
END;
|
||||
EXCEPT
|
||||
| BadSedol(text) => IO.Put(text & "\n", Stdio.stderr);
|
||||
END;
|
||||
END SEDOL.
|
||||
16
Task/SEDOLs/Nim/sedols.nim
Normal file
16
Task/SEDOLs/Nim/sedols.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
proc c2v(c: char): int =
|
||||
assert c notin "AEIOU"
|
||||
if c < 'A': ord(c) - ord('0') else: ord(c) - ord('7')
|
||||
|
||||
const weight = [1, 3, 1, 7, 3, 9]
|
||||
|
||||
proc checksum(sedol: string): char =
|
||||
var val = 0
|
||||
for i, ch in sedol:
|
||||
val += c2v(ch) * weight[i]
|
||||
result = chr((10 - val mod 10) mod 10 + ord('0'))
|
||||
|
||||
for sedol in ["710889", "B0YBKJ", "406566", "B0YBLH",
|
||||
"228276", "B0YBKL", "557910", "B0YBKR",
|
||||
"585284", "B0YBKT", "B00030"]:
|
||||
echo sedol, " → ", sedol & checksum(sedol)
|
||||
28
Task/SEDOLs/OCaml/sedols.ocaml
Normal file
28
Task/SEDOLs/OCaml/sedols.ocaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
let char2value c =
|
||||
assert (not (String.contains "AEIOU" c));
|
||||
match c with
|
||||
| '0'..'9' -> int_of_char c - int_of_char '0'
|
||||
| 'A'..'Z' -> int_of_char c - int_of_char 'A' + 10
|
||||
| _ -> assert false
|
||||
|
||||
let sedolweight = [1;3;1;7;3;9]
|
||||
|
||||
let explode s =
|
||||
s |> String.to_seq |> List.of_seq
|
||||
|
||||
let checksum sedol =
|
||||
let tmp = List.fold_left2 (fun sum ch weight -> sum + char2value ch * weight)
|
||||
0 (explode sedol) sedolweight in
|
||||
string_of_int ((10 - (tmp mod 10)) mod 10) ;;
|
||||
|
||||
List.iter (fun sedol -> print_endline (sedol ^ checksum sedol))
|
||||
[ "710889";
|
||||
"B0YBKJ";
|
||||
"406566";
|
||||
"B0YBLH";
|
||||
"228276";
|
||||
"B0YBKL";
|
||||
"557910";
|
||||
"B0YBKR";
|
||||
"585284";
|
||||
"B0YBKT" ]
|
||||
5
Task/SEDOLs/Oforth/sedols.fth
Normal file
5
Task/SEDOLs/Oforth/sedols.fth
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
func: sedol(s)
|
||||
[ 1, 3, 1, 7, 3, 9 ] s
|
||||
zipWith(#[ dup isDigit ifTrue: [ '0' - ] else: [ 'A' - 10 + ] * ]) sum
|
||||
10 mod 10 swap - 10 mod
|
||||
StringBuffer new s << swap '0' + <<c ;
|
||||
26
Task/SEDOLs/PHP/sedols.php
Normal file
26
Task/SEDOLs/PHP/sedols.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
function char2value($c) {
|
||||
assert(stripos('AEIOU', $c) === FALSE);
|
||||
return intval($c, 36);
|
||||
}
|
||||
|
||||
$sedolweight = array(1,3,1,7,3,9);
|
||||
|
||||
function checksum($sedol) {
|
||||
global $sedolweight;
|
||||
$tmp = array_sum(array_map(create_function('$ch, $weight', 'return char2value($ch) * $weight;'),
|
||||
str_split($sedol), $sedolweight)
|
||||
);
|
||||
return strval((10 - ($tmp % 10)) % 10);
|
||||
}
|
||||
|
||||
foreach (array('710889',
|
||||
'B0YBKJ',
|
||||
'406566',
|
||||
'B0YBLH',
|
||||
'228276',
|
||||
'B0YBKL',
|
||||
'557910',
|
||||
'B0YBKR',
|
||||
'585284',
|
||||
'B0YBKT') as $sedol)
|
||||
echo $sedol, checksum($sedol), "\n";
|
||||
23
Task/SEDOLs/PL-I/sedols.pli
Normal file
23
Task/SEDOLs/PL-I/sedols.pli
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Compute SEDOLs; includes check for invalid characters. */
|
||||
sedol: procedure options (main); /* 3 March 2012 */
|
||||
declare alphabet character (36) static initial
|
||||
('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ');
|
||||
declare weight (6) fixed static initial (1, 3, 1, 7, 3, 9);
|
||||
declare s character (6);
|
||||
declare (i, v, k) fixed;
|
||||
|
||||
do while ('1'b);
|
||||
get edit (s) (a(6));
|
||||
put skip edit (s) (a);
|
||||
/* Check for invalid characters: */
|
||||
if verify(s, '0123456789BCDFGHJKLMNPQRSTVWXYZ') > 0 then stop;
|
||||
v = 0;
|
||||
do i = 1 to 6;
|
||||
k = index(alphabet, substr(s, i, 1)) - 1;
|
||||
v = v + weight(i) * k;
|
||||
end;
|
||||
k = mod(v, 10);
|
||||
v = mod(10 - k, 10);
|
||||
put edit (s, v) (x(2), a, f(1)); put edit (' ') (a);
|
||||
end;
|
||||
end sedol;
|
||||
45
Task/SEDOLs/Pascal/sedols.pas
Normal file
45
Task/SEDOLs/Pascal/sedols.pas
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
program Sedols(output);
|
||||
|
||||
function index(c: char): integer;
|
||||
const
|
||||
alpha = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
index := 0;
|
||||
for i := low(alpha) to high(alpha) do
|
||||
if c = alpha[i] then
|
||||
index := i;
|
||||
end;
|
||||
|
||||
function checkdigit(c: string): char;
|
||||
const
|
||||
weight: array [1..6] of integer = (1, 3, 1, 7, 3, 9);
|
||||
var
|
||||
i, sum: integer;
|
||||
begin
|
||||
sum := 0;
|
||||
for i := 1 to 6 do
|
||||
sum := sum + (index(c[i]) - 1) * weight[i];
|
||||
checkdigit := char((10 - (sum mod 10)) mod 10 + 48);
|
||||
end;
|
||||
|
||||
const
|
||||
codes: array [1..11] of string =
|
||||
('710889', 'B0YBKJ', '406566', 'B0YBLH',
|
||||
'228276', 'B0YBKL', '557910', 'B0YBKR',
|
||||
'585284', 'B0YBKT', 'B00030');
|
||||
|
||||
var
|
||||
seforl: string;
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
for i := low(codes) to high(codes) do
|
||||
begin
|
||||
seforl := codes[i];
|
||||
setlength(seforl, 7);
|
||||
seforl[7] := checkdigit(codes[i]);
|
||||
writeln(codes[i], ' -> ', seforl);
|
||||
end;
|
||||
end.
|
||||
26
Task/SEDOLs/Perl/sedols.pl
Normal file
26
Task/SEDOLs/Perl/sedols.pl
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use List::Util qw(sum);
|
||||
use POSIX qw(strtol);
|
||||
|
||||
sub zip :prototype(&\@\@) {
|
||||
my $f = shift;
|
||||
my @a = @{shift()};
|
||||
my @b = @{shift()};
|
||||
my @result;
|
||||
push(@result, $f->(shift @a, shift @b)) while @a && @b;
|
||||
return @result;
|
||||
}
|
||||
|
||||
my @weights = (1, 3, 1, 7, 3, 9);
|
||||
sub sedan :prototype($) {
|
||||
my $s = shift;
|
||||
$s =~ /[AEIOU]/ and die "No vowels";
|
||||
my @vs = map {(strtol $_, 36)[0]} split //, $s;
|
||||
my $checksum = sum (zip {$_[0] * $_[1]} @vs, @weights);
|
||||
my $check_digit = (10 - $checksum % 10) % 10;
|
||||
return $s . $check_digit;
|
||||
}
|
||||
|
||||
while (<>) {
|
||||
chomp;
|
||||
print sedol($_), "\n";
|
||||
}
|
||||
34
Task/SEDOLs/Phix/sedols.phix
Normal file
34
Task/SEDOLs/Phix/sedols.phix
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">type</span> <span style="color: #000000;">string6</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">6</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
|
||||
|
||||
<span style="color: #008080;">type</span> <span style="color: #000000;">sedolch</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'Z'</span> <span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'9'</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"AEIOU"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">sedol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">string6</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">sedolch</span> <span style="color: #000000;">c</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">6</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">?</span><span style="color: #000000;">c</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">10</span><span style="color: #0000FF;">:</span><span style="color: #000000;">c</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)*{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">}[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">&</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #008000;">'0'</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"710889"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"B0YBKJ"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"406566"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"B0YBLH"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"228276"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"B0YBKL"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"557910"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"B0YBKR"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"585284"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"B0YBKT"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"B00030"</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">sedol</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
18
Task/SEDOLs/Phixmonti/sedols.phixmonti
Normal file
18
Task/SEDOLs/Phixmonti/sedols.phixmonti
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
include ..\Utilitys.pmt
|
||||
|
||||
def ->7DOL
|
||||
( 1 3 1 7 3 9 ) var weights
|
||||
0 >ps
|
||||
6 for >ps
|
||||
tps get
|
||||
dup 65 >= if 7 - endif 48 -
|
||||
weights ps> get nip * ps> + >ps
|
||||
endfor
|
||||
10 ps> 10 mod - 10 mod tostr chain
|
||||
enddef
|
||||
|
||||
( "710889" "B0YBKJ" "406566" "B0YBLH" "228276" "B0YBKL" "557910" "B0YBKR" "585284" "B0YBKT" "B00030" )
|
||||
|
||||
getid ->7DOL map
|
||||
|
||||
pstack
|
||||
21
Task/SEDOLs/PicoLisp/sedols.l
Normal file
21
Task/SEDOLs/PicoLisp/sedols.l
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
(de sedol (Str)
|
||||
(pack Str
|
||||
(char
|
||||
(+ `(char "0")
|
||||
(%
|
||||
(- 10
|
||||
(%
|
||||
(sum
|
||||
'((W C)
|
||||
(cond
|
||||
((>= "9" C "0")
|
||||
(* W (format C)) )
|
||||
((>= "Z" (setq C (uppc C)) "A")
|
||||
(* W (+ 10 (- (char C) `(char "A")))) ) ) )
|
||||
(1 3 1 7 3 9)
|
||||
(chop Str) )
|
||||
10 ) )
|
||||
10 ) ) ) ) )
|
||||
|
||||
(for S '("710889" "B0YBKJ" "406566" "B0YBLH" "228276" "B0YBKL" "557910" "B0YBKR" "585284" "B0YBKT" "B00030")
|
||||
(prinl (sedol S)) )
|
||||
13
Task/SEDOLs/Potion/sedols.potion
Normal file
13
Task/SEDOLs/Potion/sedols.potion
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
sedolnum = (c) :
|
||||
if ("0" ord <= c ord and c ord <= "9" ord): c number integer.
|
||||
else: 10 + c ord - "A" ord.
|
||||
.
|
||||
|
||||
sedol = (str) :
|
||||
weight = (1, 3, 1, 7, 3, 9)
|
||||
sum = 0
|
||||
6 times (i) :
|
||||
sum = sum + sedolnum(str(i)) * weight(i)
|
||||
.
|
||||
(str, (10 - (sum % 10)) % 10) join
|
||||
.
|
||||
48
Task/SEDOLs/PowerShell/sedols.psh
Normal file
48
Task/SEDOLs/PowerShell/sedols.psh
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
function Add-SEDOLCheckDigit
|
||||
{
|
||||
Param ( # Validate input as six-digit SEDOL number
|
||||
[ValidatePattern( "^[0123456789bcdfghjklmnpqrstvwxyz]{6}$" )]
|
||||
[parameter ( Mandatory = $True ) ]
|
||||
[string]
|
||||
$SixDigitSEDOL )
|
||||
|
||||
# Convert to array of single character strings, using type char as an intermediary
|
||||
$SEDOL = [string[]][char[]]$SixDigitSEDOL
|
||||
|
||||
# Define place weights
|
||||
$Weight = @( 1, 3, 1, 7, 3, 9 )
|
||||
|
||||
# Define character values (implicit in 0-based location within string)
|
||||
$Characters = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
$CheckSum = 0
|
||||
|
||||
# For each digit, multiply the character value by the weight and add to check sum
|
||||
0..5 | ForEach { $CheckSum += $Characters.IndexOf( $SEDOL[$_].ToLower() ) * $Weight[$_] }
|
||||
|
||||
# Derive the check digit from the partial check sum
|
||||
$CheckDigit = ( 10 - $CheckSum % 10 ) % 10
|
||||
|
||||
# Return concatenated result
|
||||
return ( $SixDigitSEDOL + $CheckDigit )
|
||||
}
|
||||
|
||||
# Test
|
||||
$List = @(
|
||||
"710889"
|
||||
"B0YBKJ"
|
||||
"406566"
|
||||
"B0YBLH"
|
||||
"228276"
|
||||
"B0YBKL"
|
||||
"557910"
|
||||
"B0YBKR"
|
||||
"585284"
|
||||
"B0YBKT"
|
||||
"B00030"
|
||||
)
|
||||
|
||||
ForEach ( $PartialSEDOL in $List )
|
||||
{
|
||||
Add-SEDOLCheckDigit -SixDigitSEDOL $PartialSEDOL
|
||||
}
|
||||
40
Task/SEDOLs/PureBasic/sedols.basic
Normal file
40
Task/SEDOLs/PureBasic/sedols.basic
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
Procedure.s SEDOLs(rawstring$)
|
||||
Protected i, j, sum, c, m
|
||||
For i=1 To Len(rawstring$)
|
||||
c=Asc(Mid(rawstring$,i,1))
|
||||
Select c
|
||||
Case Asc("0") To Asc("9")
|
||||
j=Val(Mid(rawstring$,i,1))
|
||||
Default
|
||||
j=c-Asc("A")
|
||||
EndSelect
|
||||
Select i
|
||||
Case 1, 3, 7: m=1
|
||||
Case 2, 5: m=3
|
||||
Case 4: m=7
|
||||
Default: m=9
|
||||
EndSelect
|
||||
sum+j*m
|
||||
Next
|
||||
sum=(10-(sum%10))%10
|
||||
ProcedureReturn rawstring$+Str(sum)
|
||||
EndProcedure
|
||||
|
||||
Define result$, i
|
||||
Restore Tests
|
||||
For i=0 To 10
|
||||
Read.s SEDOL$
|
||||
result$+SEDOLs(SEDOL$)
|
||||
If i%2
|
||||
result$+#CRLF$
|
||||
ElseIf i<10
|
||||
result$+", "
|
||||
EndIf
|
||||
Next
|
||||
MessageRequester("SEDOLs","Result"+#CRLF$+result$)
|
||||
|
||||
DataSection
|
||||
Tests:
|
||||
Data.s "710889","B0YBKJ","406566","B0YBLH","228276"
|
||||
Data.s "B0YBKL","557910","B0YBKR","585284","B0YBKT","B00030"
|
||||
EndDataSection
|
||||
25
Task/SEDOLs/Python/sedols-1.py
Normal file
25
Task/SEDOLs/Python/sedols-1.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
def char2value(c):
|
||||
assert c not in 'AEIOU', "No vowels"
|
||||
return int(c, 36)
|
||||
|
||||
sedolweight = [1,3,1,7,3,9]
|
||||
|
||||
def checksum(sedol):
|
||||
tmp = sum(map(lambda ch, weight: char2value(ch) * weight,
|
||||
sedol, sedolweight)
|
||||
)
|
||||
return str((10 - (tmp % 10)) % 10)
|
||||
|
||||
for sedol in '''
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
'''.split():
|
||||
print sedol + checksum(sedol)
|
||||
125
Task/SEDOLs/Python/sedols-2.py
Normal file
125
Task/SEDOLs/Python/sedols-2.py
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
'''SEDOL checksum digits'''
|
||||
|
||||
from functools import reduce
|
||||
|
||||
|
||||
# sedolCheckSumDigitLR :: String -> Either String Char
|
||||
def sedolCheckSumDigitLR(s):
|
||||
'''Either an explanatory message, or a
|
||||
checksum digit character to append
|
||||
to a given six-character SEDOL string.
|
||||
'''
|
||||
def goLR(lr, cn):
|
||||
c, n = cn
|
||||
return bindLR(lr)(
|
||||
lambda a: bindLR(sedolValLR(c))(
|
||||
lambda x: Right(a + x * n)
|
||||
)
|
||||
)
|
||||
return bindLR(
|
||||
reduce(
|
||||
goLR,
|
||||
zip(s, [1, 3, 1, 7, 3, 9]),
|
||||
Right(0)
|
||||
)
|
||||
)(lambda d: Right(str((10 - (d % 10)) % 10)))
|
||||
|
||||
|
||||
# sedolValLR :: Char -> Either String Char
|
||||
def sedolValLR(c):
|
||||
'''Either an explanatory message, or the
|
||||
SEDOL value of a given character.
|
||||
'''
|
||||
return Right(int(c, 36)) if (
|
||||
c not in 'AEIOU'
|
||||
) else Left('Unexpected vowel in SEDOL string: ' + c)
|
||||
|
||||
|
||||
# TEST -------------------------------------------------
|
||||
def main():
|
||||
'''Append checksums where valid.'''
|
||||
|
||||
print(
|
||||
fTable(__doc__ + ':\n')(str)(
|
||||
either(str)(str)
|
||||
)(sedolCheckSumDigitLR)(
|
||||
'''710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
BOYBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030
|
||||
'''.split()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
|
||||
# Left :: a -> Either a b
|
||||
def Left(x):
|
||||
'''Constructor for an empty Either (option type) value
|
||||
with an associated string.'''
|
||||
return {'type': 'Either', 'Right': None, 'Left': x}
|
||||
|
||||
|
||||
# Right :: b -> Either a b
|
||||
def Right(x):
|
||||
'''Constructor for a populated Either (option type) value'''
|
||||
return {'type': 'Either', 'Left': None, 'Right': x}
|
||||
|
||||
|
||||
# bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
|
||||
def bindLR(m):
|
||||
'''Either monad injection operator.
|
||||
Two computations sequentially composed,
|
||||
with any value produced by the first
|
||||
passed as an argument to the second.'''
|
||||
return lambda mf: (
|
||||
mf(m.get('Right')) if None is m.get('Left') else m
|
||||
)
|
||||
|
||||
|
||||
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
def compose(g):
|
||||
'''Right to left function composition.'''
|
||||
return lambda f: lambda x: g(f(x))
|
||||
|
||||
|
||||
# either :: (a -> c) -> (b -> c) -> Either a b -> c
|
||||
def either(fl):
|
||||
'''The application of fl to e if e is a Left value,
|
||||
or the application of fr to e if e is a Right value.'''
|
||||
return lambda fr: lambda e: fl(e['Left']) if (
|
||||
None is e['Right']
|
||||
) else fr(e['Right'])
|
||||
|
||||
|
||||
# fTable :: String -> (a -> String) ->
|
||||
# (b -> String) ->
|
||||
# (a -> b) -> [a] -> String
|
||||
def fTable(s):
|
||||
'''Heading -> x display function -> fx display function ->
|
||||
f -> value list -> tabular string.'''
|
||||
def go(xShow, fxShow, f, xs):
|
||||
w = max(map(compose(len)(xShow), xs))
|
||||
return s + '\n' + '\n'.join([
|
||||
xShow(x).rjust(w, ' ') + ' -> ' + fxShow(f(x)) for x in xs
|
||||
])
|
||||
return lambda xShow: lambda fxShow: (
|
||||
lambda f: lambda xs: go(
|
||||
xShow, fxShow, f, xs
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
8
Task/SEDOLs/Q/sedols.q
Normal file
8
Task/SEDOLs/Q/sedols.q
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
scd:{
|
||||
v:{("i"$x) - ?[("0"<=x) & x<="9"; "i"$"0"; -10+"i"$"A"]} each x; / Turn characters of SEDOL into their values
|
||||
w:sum v*1 3 1 7 3 9; / Weighted sum of values
|
||||
d:(10 - w mod 10) mod 10; / Check digit value
|
||||
x,"c"$(("i"$"0")+d) / Append to SEDOL
|
||||
}
|
||||
|
||||
scd each ("710889";"B0YBKJ";"406566";"B0YBLH";"228276";"B0YBKL";"557910";"B0YBKR";"585284";"B0YBKT";"B00030")
|
||||
14
Task/SEDOLs/Quackery/sedols.quackery
Normal file
14
Task/SEDOLs/Quackery/sedols.quackery
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[ 48 - dup 9 > if [ 7 - ] ] is chvalue ( c --> n )
|
||||
|
||||
[ 0 over witheach
|
||||
[ chvalue
|
||||
' [ 1 3 1 7 3 9 ]
|
||||
i^ peek * + ]
|
||||
10 mod 10 swap - 10 mod
|
||||
48 + join ] is ->sedol ( $ --> $ )
|
||||
|
||||
$ "710889 B0YBKJ 406566 B0YBLH
|
||||
228276 B0YBKL 557910 B0YBKR
|
||||
585284 B0YBKT B00030" nest$
|
||||
|
||||
witheach [ ->sedol echo$ cr ]
|
||||
37
Task/SEDOLs/R/sedols.r
Normal file
37
Task/SEDOLs/R/sedols.r
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Read in data from text connection
|
||||
datalines <- readLines(tc <- textConnection("710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT")); close(tc)
|
||||
|
||||
# Check data valid
|
||||
checkSedol <- function(datalines)
|
||||
{
|
||||
ok <- grep("^[[:digit:][:upper:]]{6}$", datalines)
|
||||
if(length(ok) < length(datalines))
|
||||
{
|
||||
stop("there are invalid lines")
|
||||
}
|
||||
}
|
||||
checkSedol(datalines)
|
||||
|
||||
# Append check digit
|
||||
appendCheckDigit <- function(x)
|
||||
{
|
||||
if(length(x) > 1) return(sapply(x, appendCheckDigit))
|
||||
ascii <- as.integer(charToRaw(x))
|
||||
scores <- ifelse(ascii < 65, ascii - 48, ascii - 55)
|
||||
weights <- c(1, 3, 1, 7, 3, 9)
|
||||
chkdig <- (10 - sum(scores * weights) %% 10) %% 10
|
||||
paste(x, as.character(chkdig), sep="")
|
||||
}
|
||||
withchkdig <- appendCheckDigit(datalines)
|
||||
|
||||
#Print in format requested
|
||||
writeLines(withchkdig)
|
||||
42
Task/SEDOLs/REXX/sedols.rexx
Normal file
42
Task/SEDOLs/REXX/sedols.rexx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*REXX program computes the check digit (last digit) for six or seven character SEDOLs.*/
|
||||
@abcU = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' /*the uppercase Latin alphabet. */
|
||||
alphaDigs= '0123456789'@abcU /*legal characters, and then some. */
|
||||
allowable=space(translate(alphaDigs,,'AEIOU'),0) /*remove the vowels from the alphabet. */
|
||||
weights = 1317391 /*various weights for SEDOL characters.*/
|
||||
@.= /* [↓] the ARG statement capitalizes. */
|
||||
arg @.1 . /*allow a user─specified SEDOL from CL*/
|
||||
if @.1=='' then do /*if none, then assume eleven defaults.*/
|
||||
@.1 = 710889 /*if all numeric, we don't need quotes.*/
|
||||
@.2 = 'B0YBKJ'
|
||||
@.3 = 406566
|
||||
@.4 = 'B0YBLH'
|
||||
@.5 = 228276
|
||||
@.6 = 'B0YBKL'
|
||||
@.7 = 557910
|
||||
@.8 = 'B0YBKR'
|
||||
@.9 = 585284
|
||||
@.10 = 'B0YBKT'
|
||||
@.11 = 'B00030'
|
||||
end
|
||||
|
||||
do j=1 while @.j\==''; sedol=@.j /*process each of the specified SEDOLs.*/
|
||||
L=length(sedol)
|
||||
if L<6 | L>7 then call ser "SEDOL isn't a valid length"
|
||||
if left(sedol,1)==9 then call swa 'SEDOL is reserved for end user allocation'
|
||||
_=verify(sedol, allowable)
|
||||
if _\==0 then call ser 'illegal character in SEDOL:' substr(sedol, _, 1)
|
||||
sum=0 /*the checkDigit sum (so far). */
|
||||
do k=1 for 6 /*process each character in the SEDOL. */
|
||||
sum=sum + ( pos( substr(sedol, k, 1), alphaDigs) -1) * substr(weights, k, 1)
|
||||
end /*k*/
|
||||
|
||||
chkDig= (10-sum//10) // 10
|
||||
r=right(sedol, 1)
|
||||
if L==7 & chkDig\==r then call ser sedol, 'invalid check digit:' r
|
||||
say 'SEDOL:' left(sedol,15) 'SEDOL + check digit ───► ' left(sedol,6)chkDig
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sed: say; say 'SEDOL:' sedol; say; return
|
||||
ser: say; say '***error***' arg(1); call sed; exit 13
|
||||
swa: say; say '***warning***' arg(1); say; return
|
||||
63
Task/SEDOLs/Racket/sedols.rkt
Normal file
63
Task/SEDOLs/Racket/sedols.rkt
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#lang racket
|
||||
;;; Since the Task gives us unchecksummed and checksummed SEDOLs, and
|
||||
;;; we'll just take a list of the output SEDOLs and remove their last
|
||||
;;; characters for the input
|
||||
(define output-SEDOLS
|
||||
(list "7108899" "B0YBKJ7" "4065663"
|
||||
"B0YBLH2" "2282765" "B0YBKL9"
|
||||
"5579107" "B0YBKR5" "5852842"
|
||||
"B0YBKT7" "B000300"))
|
||||
(define (output->input-SEDOL S) (substring S 0 6))
|
||||
(define input-SEDOLS (map output->input-SEDOL output-SEDOLS))
|
||||
|
||||
;;; checksum calculation
|
||||
(define (SEDOL-character-value c)
|
||||
(if (char-numeric? c)
|
||||
(- (char->integer c) (char->integer #\0))
|
||||
(+ 10 (- (char->integer c) (char->integer #\A)))))
|
||||
(define (SEDOL-character-sum S)
|
||||
(for/sum ((c S) ; if we run out of c's before the final 1 in weight, we'll have the unchecksummed weighted sum
|
||||
(weight (in-list '(1 3 1 7 3 9 1))))
|
||||
(* weight (SEDOL-character-value c))))
|
||||
(define (SEDOL-checksum S) (number->string (modulo (- 10 (SEDOL-character-sum S)) 10)))
|
||||
|
||||
;;; build output from input
|
||||
(define (SEDOL-append-checksum S) (string-append S (SEDOL-checksum S)))
|
||||
|
||||
;;; Extra credit -- according to wikipedia:
|
||||
;;; "SEDOLs are seven characters in length"
|
||||
;;; "vowels are never used"
|
||||
;;; there seems to be no statement as to case, but we'll assert that too!
|
||||
;;;
|
||||
;;; valid-SEDOL? is a predicate... it doesn't report a reason
|
||||
(define (invalid-SEDOL? S)
|
||||
(define (invalid-SEDOL-character? c)
|
||||
(if
|
||||
(and (not (char-upper-case? c)) (not (char-numeric? c)))
|
||||
(format "contains non upper case/non numeric ~a" c)
|
||||
(case c [(#\A #\E #\I #\O #\U) (format "contains vowel ~a" c)] [else #f])))
|
||||
(cond
|
||||
[(< (string-length S) 7) "too few characters"]
|
||||
[(> (string-length S) 7) "too many characters"]
|
||||
[(not (zero? (modulo (SEDOL-character-sum S) 10))) "invalid checksum"]
|
||||
[(for/first ((c S) #:when (invalid-SEDOL-character? c)) c) => identity]
|
||||
[else #f])) ; a.k.a. valid!
|
||||
|
||||
(module+ main
|
||||
(for* ((S input-SEDOLS))
|
||||
(displayln (SEDOL-append-checksum S)))
|
||||
(newline)
|
||||
(displayln "Extra Credit!")
|
||||
(displayln (invalid-SEDOL? "B0YBKT7")) ; expect #f output
|
||||
(displayln (invalid-SEDOL? "B000301")) ; expect "invalid checksum" output
|
||||
)
|
||||
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
(check-= (SEDOL-character-value #\3) 3 0)
|
||||
(check-= (SEDOL-character-value #\B) 11 0)
|
||||
(check-equal? (invalid-SEDOL? "B000301") "invalid checksum")
|
||||
(for ((S output-SEDOLS))
|
||||
(check-false (invalid-SEDOL? S))
|
||||
(check-equal? (SEDOL-append-checksum (substring S 0 6))
|
||||
S (format "test SEDOL for ~a" S))))
|
||||
26
Task/SEDOLs/Raku/sedols.raku
Normal file
26
Task/SEDOLs/Raku/sedols.raku
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
sub sedol( Str $s ) {
|
||||
die 'No vowels allowed' if $s ~~ /<[AEIOU]>/;
|
||||
die 'Invalid format' if $s !~~ /^ <[0..9B..DF..HJ..NP..TV..Z]>**6 $ /;
|
||||
|
||||
my %base36 = (flat 0..9, 'A'..'Z') »=>« ^36;
|
||||
my @weights = 1, 3, 1, 7, 3, 9;
|
||||
|
||||
my @vs = %base36{ $s.comb };
|
||||
my $checksum = [+] @vs Z* @weights;
|
||||
my $check_digit = (10 - $checksum % 10) % 10;
|
||||
return $s ~ $check_digit;
|
||||
}
|
||||
|
||||
say sedol($_) for <
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030
|
||||
>;
|
||||
24
Task/SEDOLs/Ring/sedols.ring
Normal file
24
Task/SEDOLs/Ring/sedols.ring
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
see sedol("710889") + nl
|
||||
see sedol("B0YBKJ") + nl
|
||||
see sedol("406566") + nl
|
||||
see sedol("B0YBLH") + nl
|
||||
see sedol("228276") + nl
|
||||
see sedol("B0YBKL") + nl
|
||||
see sedol("557910") + nl
|
||||
see sedol("B0YBKR") + nl
|
||||
see sedol("585284") + nl
|
||||
see sedol("B0YBKT") + nl
|
||||
see sedol("B00030") + nl
|
||||
|
||||
func sedol d
|
||||
d = upper(d)
|
||||
s = 0
|
||||
weights = [1, 3, 1, 7, 3, 9]
|
||||
for i = 1 to 6
|
||||
a = substr(d,i,1)
|
||||
if ascii(a) >= 48 and ascii(a) <= 57
|
||||
s += number(a) * weights[i]
|
||||
else
|
||||
s += (ascii(a) - 55) * weights[i] ok
|
||||
next
|
||||
return d + (10 - (s % 10)) % 10
|
||||
37
Task/SEDOLs/Ruby/sedols.rb
Normal file
37
Task/SEDOLs/Ruby/sedols.rb
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
Sedol_char = "0123456789BCDFGHJKLMNPQRSTVWXYZ"
|
||||
Sedolweight = [1,3,1,7,3,9]
|
||||
|
||||
def char2value(c)
|
||||
raise ArgumentError, "Invalid char #{c}" unless Sedol_char.include?(c)
|
||||
c.to_i(36)
|
||||
end
|
||||
|
||||
def checksum(sedol)
|
||||
raise ArgumentError, "Invalid length" unless sedol.size == Sedolweight.size
|
||||
sum = sedol.chars.zip(Sedolweight).sum{|ch, weight| char2value(ch) * weight }
|
||||
((10 - (sum % 10)) % 10).to_s
|
||||
end
|
||||
|
||||
data = %w(710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030
|
||||
C0000
|
||||
1234567
|
||||
00000A)
|
||||
|
||||
data.each do |sedol|
|
||||
print "%-8s " % sedol
|
||||
begin
|
||||
puts sedol + checksum(sedol)
|
||||
rescue => e
|
||||
p e
|
||||
end
|
||||
end
|
||||
45
Task/SEDOLs/Rust/sedols.rust
Normal file
45
Task/SEDOLs/Rust/sedols.rust
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
fn sedol(input: &str) -> Option<String> {
|
||||
let weights = vec![1, 3, 1, 7, 3, 9, 1];
|
||||
let valid_chars = "0123456789BCDFGHJKLMNPQRSTVWXYZ";
|
||||
|
||||
if input.len() != 6 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// could be done by regex if needed
|
||||
for c in input.chars() {
|
||||
if !valid_chars.contains(c) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
let mut result: u32 = input
|
||||
.chars()
|
||||
.map(|c| {
|
||||
if c.is_digit(10) {
|
||||
c as u32 - 48
|
||||
} else {
|
||||
c as u32 - 55
|
||||
}
|
||||
})
|
||||
.zip(weights)
|
||||
.map(|(cnum, w)| w * cnum)
|
||||
.collect::<Vec<u32>>()
|
||||
.iter()
|
||||
.sum();
|
||||
|
||||
result = (10 - result % 10) % 10;
|
||||
|
||||
Some(input.to_owned() + &result.to_string())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let inputs = vec![
|
||||
"710889", "B0YBKJ", "406566", "B0YBLH", "228276", "B0YBKL", "557910", "B0YBKR", "585284",
|
||||
"B0YBKT", "B00030",
|
||||
];
|
||||
|
||||
for input in inputs {
|
||||
println!("{} SEDOL: {:?}", &input, sedol(&input).unwrap());
|
||||
}
|
||||
}
|
||||
64
Task/SEDOLs/SQL-PL/sedols.sql
Normal file
64
Task/SEDOLs/SQL-PL/sedols.sql
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
--#SET TERMINATOR @
|
||||
|
||||
SET SERVEROUTPUT ON@
|
||||
|
||||
CREATE OR REPLACE FUNCTION CHECK_SEDOL (
|
||||
IN TEXT VARCHAR(6)
|
||||
) RETURNS VARCHAR(7)
|
||||
BEGIN
|
||||
DECLARE TYPE SEDOL AS CHAR(1) ARRAY [6];
|
||||
--declare text varchar(6) default 'B12345';
|
||||
DECLARE WEIGHT SEDOL;
|
||||
DECLARE I SMALLINT;
|
||||
DECLARE SENTENCE VARCHAR(256);
|
||||
DECLARE CHAR_AT CHAR(1);
|
||||
DECLARE OUTPUT CHAR(1);
|
||||
DECLARE SUM SMALLINT;
|
||||
DECLARE CHECK SMALLINT;
|
||||
DECLARE INVALID_CHAR CONDITION FOR SQLSTATE '22004' ;
|
||||
DECLARE STMT STATEMENT;
|
||||
|
||||
-- Converts all to upper.
|
||||
SET TEXT = UPPER (TEXT);
|
||||
-- CALL DBMS_OUTPUT.PUT_LINE(TEXT);
|
||||
-- Checks the characters.
|
||||
SET I = 1;
|
||||
WHILE (I <= 6) DO
|
||||
SET CHAR_AT = SUBSTR(TEXT, I, 1);
|
||||
-- CALL DBMS_OUTPUT.PUT_LINE('Char ' || CHAR_AT);
|
||||
SET SENTENCE = 'SET ? = (SELECT SEDOL FROM (SELECT ''' || CHAR_AT
|
||||
|| ''' SEDOL FROM SYSIBM.SYSDUMMY1) WHERE SEDOL IN (''B'',''C'',''D'',''F'',''G'',''H'',''J'','
|
||||
|| '''K'',''L'',''M'',''N'',''P'',''Q'',''R'',''S'',''T'',''V'',''W'',''X'',''Y'',''Z'',''0'','
|
||||
|| '''1'',''2'',''3'',''4'',''5'',''6'',''7'',''8'',''9''))';
|
||||
PREPARE STMT FROM SENTENCE;
|
||||
EXECUTE STMT INTO OUTPUT;
|
||||
IF (OUTPUT IS NULL) THEN
|
||||
SIGNAL INVALID_CHAR;
|
||||
END IF;
|
||||
SET I = I + 1;
|
||||
END WHILE;
|
||||
|
||||
-- Assigns weight
|
||||
SET WEIGHT[1] = '1';
|
||||
SET WEIGHT[2] = '3';
|
||||
SET WEIGHT[3] = '1';
|
||||
SET WEIGHT[4] = '7';
|
||||
SET WEIGHT[5] = '3';
|
||||
SET WEIGHT[6] = '9';
|
||||
|
||||
-- Process the SEDOL.
|
||||
SET SUM = 0;
|
||||
SET I = 1;
|
||||
WHILE (I <= 6) DO
|
||||
SET CHAR_AT = SUBSTR(TEXT, I, 1);
|
||||
IF (ASCII(CHAR_AT) > 65) THEN
|
||||
SET SUM = SUM + WEIGHT[I] * (ASCII(CHAR_AT) - 64 + 9);
|
||||
ELSE
|
||||
SET SUM = SUM + WEIGHT[I] * CHAR_AT;
|
||||
END IF;
|
||||
SET I = I + 1;
|
||||
END WHILE;
|
||||
SET CHECK = MOD((10 - MOD(SUM, 10)), 10);
|
||||
CALL DBMS_OUTPUT.PUT_LINE(CHECK);
|
||||
RETURN TEXT || CHECK;
|
||||
END @
|
||||
7
Task/SEDOLs/Scala/sedols.scala
Normal file
7
Task/SEDOLs/Scala/sedols.scala
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
class SEDOL(s: String) {
|
||||
require(s.size == 6 || s.size == 7, "SEDOL length must be 6 or 7 characters")
|
||||
require(s.size == 6 || s(6).asDigit == chksum, "Incorrect SEDOL checksum")
|
||||
require(s forall (c => !("aeiou" contains c.toLower)), "Vowels not allowed in SEDOL")
|
||||
def chksum = 10 - ((s zip List(1, 3, 1, 7, 3, 9) map { case (c, w) => c.asDigit * w } sum) % 10)
|
||||
override def toString = s.take(6) + chksum
|
||||
}
|
||||
35
Task/SEDOLs/Seed7/sedols.seed7
Normal file
35
Task/SEDOLs/Seed7/sedols.seed7
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
$ include "seed7_05.s7i";
|
||||
|
||||
const func char: sedolCheckDigit (in string: sedol) is func
|
||||
result
|
||||
var char: checkDigit is ' ';
|
||||
local
|
||||
const array integer: weight is [] (1, 3, 1, 7, 3, 9);
|
||||
var char: ch is ' ';
|
||||
var integer: index is 0;
|
||||
var integer: item is 0;
|
||||
var integer: sum is 0;
|
||||
begin
|
||||
for ch key index range sedol do
|
||||
case ch of
|
||||
when {'0' .. '9'}:
|
||||
item := ord(ch) - ord('0');
|
||||
when {'A' .. 'Z'} - {'A', 'E', 'I', 'O', 'U'}:
|
||||
item := ord(ch) - ord('A') + 10;
|
||||
otherwise:
|
||||
raise RANGE_ERROR;
|
||||
end case;
|
||||
sum +:= item * weight[index];
|
||||
end for;
|
||||
checkDigit := chr(-sum mod 10 + ord('0'));
|
||||
end func;
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
var string: sedol is "";
|
||||
begin
|
||||
for sedol range [] ("710889", "B0YBKJ", "406566", "B0YBLH", "228276", "B0YBKL",
|
||||
"557910", "B0YBKR", "585284", "B0YBKT", "B00030") do
|
||||
writeln(sedol <& sedolCheckDigit(sedol));
|
||||
end for;
|
||||
end func;
|
||||
29
Task/SEDOLs/Sidef/sedols.sidef
Normal file
29
Task/SEDOLs/Sidef/sedols.sidef
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
func sedol(s) {
|
||||
|
||||
die 'No vowels allowed' if (s ~~ /[AEIOU]/);
|
||||
die 'Invalid format' if (s !~ /^[0-9B-DF-HJ-NP-TV-Z]{6}$/);
|
||||
|
||||
const base36 = ((@(0..9) + @('A'..'Z')) ~Z @(0..35) -> flatten.to_h);
|
||||
const weights = [1, 3, 1, 7, 3, 9];
|
||||
|
||||
var vs = [base36{ s.chars... }];
|
||||
var checksum = (vs ~Z* weights -> sum);
|
||||
var check_digit = ((10 - checksum%10) % 10);
|
||||
return (s + check_digit);
|
||||
}
|
||||
|
||||
%w(
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030
|
||||
).each { |s|
|
||||
say sedol(s);
|
||||
}
|
||||
6
Task/SEDOLs/Smalltalk/sedols-1.st
Normal file
6
Task/SEDOLs/Smalltalk/sedols-1.st
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
String extend [
|
||||
includesAnyOf: aSet [
|
||||
aSet do: [ :e | (self includes: e) ifTrue: [ ^true ] ].
|
||||
^false
|
||||
]
|
||||
].
|
||||
43
Task/SEDOLs/Smalltalk/sedols-2.st
Normal file
43
Task/SEDOLs/Smalltalk/sedols-2.st
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
Object subclass: SEDOL [
|
||||
|weight charList|
|
||||
|
||||
initialize [
|
||||
weight := Array from: { 1. 3. 1. 7. 3. 9 }.
|
||||
charList :=
|
||||
('ABCDEFGHIJKLMNOPQRSTUVWXYZ' asOrderedCollection)
|
||||
collect: [ :c | ('AEIOU' includes: c) ifTrue: [ nil ] ifFalse: [ c ] ].
|
||||
]
|
||||
|
||||
SEDOL class >> new [
|
||||
^ (self basicNew) initialize
|
||||
]
|
||||
|
||||
"to be considered private"
|
||||
blindCheckDigit: aSEDOL [ |sum|
|
||||
sum := 0.
|
||||
aSEDOL keysAndValuesDo: [ :i :c |
|
||||
('0123456789' includes: c)
|
||||
ifTrue: [ sum := sum +
|
||||
((weight at: i) *
|
||||
(Number readFrom: (c asString readStream))).
|
||||
]
|
||||
ifFalse: [ sum := sum + (((charList indexOf: c) + 9) *
|
||||
(weight at: i))
|
||||
]
|
||||
].
|
||||
^ ((10 - (sum rem: 10)) rem: 10) displayString
|
||||
]
|
||||
|
||||
checked: aSEDOL [
|
||||
(aSEDOL size < 6) |
|
||||
(aSEDOL size > 7) |
|
||||
(aSEDOL asUppercase includesAnyOf: 'AEIOU' asSet )
|
||||
ifTrue: [ SystemExceptions.InvalidArgument
|
||||
signalOn: aSEDOL
|
||||
reason: 'Not a valid SEDOL'
|
||||
]
|
||||
ifFalse: [ |t| t := aSEDOL copyFrom: 1 to: 6.
|
||||
^ t , (self blindCheckDigit: t)
|
||||
]
|
||||
]
|
||||
].
|
||||
12
Task/SEDOLs/Smalltalk/sedols-3.st
Normal file
12
Task/SEDOLs/Smalltalk/sedols-3.st
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|sedol|
|
||||
sedol := SEDOL new.
|
||||
{ '710889'.
|
||||
'B0YBKJ'.
|
||||
'406566'.
|
||||
'B0YBLH'.
|
||||
'228276'.
|
||||
'B0YBKL'.
|
||||
'557910'.
|
||||
'B0YBKR'.
|
||||
'585284'.
|
||||
'B0YBKT' } do: [ :c | (sedol checked: c) displayNl ]
|
||||
22
Task/SEDOLs/Smalltalk/sedols-4.st
Normal file
22
Task/SEDOLs/Smalltalk/sedols-4.st
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#(
|
||||
'710889'
|
||||
'B0YBKJ'
|
||||
'406566'
|
||||
'B0YBLH'
|
||||
'228276'
|
||||
'B0YBKL'
|
||||
'557910'
|
||||
'B0YBKR'
|
||||
'585284'
|
||||
'B0YBKT'
|
||||
'B00030'
|
||||
) do:[:in |
|
||||
|um check|
|
||||
|
||||
sum := 0.
|
||||
(in to:6) with:#[1 3 1 7 3 9 ] do:[:ch :weight |
|
||||
sum := sum + (ch digitValue * weight).
|
||||
].
|
||||
check := (10 - (sum%10)) % 10.
|
||||
Transcript showCR: ( in,(Character digitValue:check))
|
||||
].
|
||||
26
Task/SEDOLs/Standard-ML/sedols.ml
Normal file
26
Task/SEDOLs/Standard-ML/sedols.ml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
fun char2value c =
|
||||
if List.exists (fn x => x = c) (explode "AEIOU") then raise Fail "no vowels"
|
||||
else if Char.isDigit c then ord c - ord #"0"
|
||||
else if Char.isUpper c then ord c - ord #"A" + 10
|
||||
else raise Match
|
||||
|
||||
val sedolweight = [1,3,1,7,3,9]
|
||||
|
||||
fun checksum sedol = let
|
||||
val tmp = ListPair.foldlEq (fn (ch, weight, sum) => sum + char2value ch * weight)
|
||||
0 (explode sedol, sedolweight)
|
||||
in
|
||||
Int.toString ((10 - (tmp mod 10)) mod 10)
|
||||
end
|
||||
|
||||
app (fn sedol => print (sedol ^ checksum sedol ^ "\n"))
|
||||
[ "710889",
|
||||
"B0YBKJ",
|
||||
"406566",
|
||||
"B0YBLH",
|
||||
"228276",
|
||||
"B0YBKL",
|
||||
"557910",
|
||||
"B0YBKR",
|
||||
"585284",
|
||||
"B0YBKT" ];
|
||||
20
Task/SEDOLs/TUSCRIPT/sedols.tu
Normal file
20
Task/SEDOLs/TUSCRIPT/sedols.tu
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
$$ MODE TUSCRIPT
|
||||
check="1'3'1'7'3'9"
|
||||
values="123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
value=STRINGS (values,":<%:")
|
||||
BUILD r_TABLE/or illegal=":A:E:I:O:U:"
|
||||
LOOP input="710889'B0YBKJ'406566'B0YBLH'228276'B0YBKL'557910'B0YBKR'585284'B0YBKT'BOYAKT'B00030",sum=""
|
||||
IF (input.ma.illegal) THEN
|
||||
PRINT/ERROR input, " illegal"
|
||||
CYCLE
|
||||
ENDIF
|
||||
strings=STRINGS (input,":<%:")
|
||||
LOOP d,nr=strings
|
||||
c=SELECT (check,#d)
|
||||
IF (nr!='digits') nr=FILTER_INDEX (value,":{nr}:",-)
|
||||
x=nr*c, sum=APPEND(sum,x)
|
||||
ENDLOOP
|
||||
endsum=SUM(sum), checksum=10-(endsum%10)
|
||||
IF (checksum==10) checksum=0
|
||||
PRINT input, " checkdigit: ", checksum
|
||||
ENDLOOP
|
||||
38
Task/SEDOLs/Tcl/sedols.tcl
Normal file
38
Task/SEDOLs/Tcl/sedols.tcl
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
namespace eval sedol {
|
||||
variable chars {0 1 2 3 4 5 6 7 8 9 "" B C D "" F G H "" J K L M N "" P Q R S T "" V W X Y Z}
|
||||
variable weight {1 3 1 7 3 9 1}
|
||||
|
||||
proc checksum {alnum6} {
|
||||
variable chars
|
||||
variable weight
|
||||
set sum 0
|
||||
set col 0
|
||||
foreach char [split [string toupper [string range $alnum6 0 5]] ""] {
|
||||
if {[set idx [lsearch -exact $chars $char]] == -1} {
|
||||
error "invalid character: $char"
|
||||
}
|
||||
incr sum [expr {$idx * [lindex $weight $col]}]
|
||||
incr col
|
||||
}
|
||||
return [expr {(10 - ($sum % 10)) % 10}]
|
||||
}
|
||||
|
||||
proc valid {alnum7} {
|
||||
expr {[checksum [string range $alnum7 0 5]] == [string index $alnum7 6]}
|
||||
}
|
||||
}
|
||||
|
||||
proc assert {condition {message "Assertion failed!"}} {
|
||||
if { ! [uplevel 1 [list expr $condition]]} {
|
||||
return -code error $message
|
||||
}
|
||||
}
|
||||
|
||||
set codes {710889 B0YBKJ 406566 B0YBLH 228276 B0YBKL 557910 B0YBKR 585284 B0YBKT}
|
||||
set answers {7108899 B0YBKJ7 4065663 B0YBLH2 2282765 B0YBKL9 5579107 B0YBKR5 5852842 B0YBKT7}
|
||||
|
||||
foreach code $codes answer $answers {
|
||||
set sedol "${code}[sedol::checksum $code]"
|
||||
assert {$sedol eq $answer} "assertion failed: $sedol ne $answer"
|
||||
puts $sedol
|
||||
}
|
||||
63
Task/SEDOLs/Transact-SQL/sedols.sql
Normal file
63
Task/SEDOLs/Transact-SQL/sedols.sql
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
CREATE FUNCTION [dbo].[fn_CheckSEDOL]
|
||||
( @SEDOL varchar(50) )
|
||||
RETURNS varchar(7)
|
||||
AS
|
||||
BEGIN
|
||||
declare @true bit = 1,
|
||||
@false bit = 0,
|
||||
@isSEDOL bit,
|
||||
@sedol_weights varchar(6) ='131739',
|
||||
@sedol_len int = LEN(@SEDOL),
|
||||
@sum int = 0
|
||||
|
||||
|
||||
if ((@sedol_len = 6))
|
||||
begin
|
||||
select @SEDOL = UPPER(@SEDOL)
|
||||
Declare @vowels varchar(5) = 'AEIOU',
|
||||
@letters varchar(21) = 'BCDFGHJKLMNPQRSTVWXYZ',
|
||||
@i int=1,
|
||||
@isStillGood bit = @true,
|
||||
@char char = '',
|
||||
@weighting int =0
|
||||
|
||||
select @isSEDOL = @false
|
||||
|
||||
while ((@i < 7) and (@isStillGood = @true))
|
||||
begin
|
||||
select @char = SUBSTRING(@SEDOL,@i,1),
|
||||
@weighting = CONVERT (INT,SUBSTRING(@sedol_weights, @i, 1))
|
||||
if (CHARINDEX(@char, @vowels) > 0) -- no vowels please
|
||||
begin
|
||||
select @isStillGood=@false
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (ISNUMERIC(@char) = @true) -- is a number
|
||||
begin
|
||||
select @sum = @sum + (ASCII(@char) - 48) * @weighting
|
||||
end
|
||||
else if (CHARINDEX(@char, @letters) = 0) -- test for the rest of the alphabet
|
||||
begin
|
||||
select @isStillGood=@false
|
||||
end
|
||||
else
|
||||
begin
|
||||
select @sum = @sum + (ASCII(@char) - 55) * @weighting
|
||||
end
|
||||
end
|
||||
select @i = @i +1
|
||||
end -- of while loop
|
||||
if (@isStillGood = @true)
|
||||
begin
|
||||
declare @checksum int = (10 - (@sum%10))%10
|
||||
select @SEDOL = @SEDOL + CONVERT(CHAR,@checksum)
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
select @SEDOL = ''
|
||||
end
|
||||
-- Return the result of the function
|
||||
RETURN @SEDOL
|
||||
END
|
||||
8
Task/SEDOLs/Ursala/sedols-1.ursala
Normal file
8
Task/SEDOLs/Ursala/sedols-1.ursala
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#import std
|
||||
#import nat
|
||||
|
||||
alphabet = digits-- ~=`A-~r letters
|
||||
weights = <1,3,1,7,3,9>
|
||||
charval = -:@rlXS num alphabet
|
||||
iprod = sum:-0+ product*p/weights+ charval*
|
||||
checksum = difference/10+ remainder\10+ iprod
|
||||
2
Task/SEDOLs/Ursala/sedols-2.ursala
Normal file
2
Task/SEDOLs/Ursala/sedols-2.ursala
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
weights = difference/*10 <1,3,1,7,3,9>
|
||||
checksum = remainder\10+ iprod
|
||||
2
Task/SEDOLs/Ursala/sedols-3.ursala
Normal file
2
Task/SEDOLs/Ursala/sedols-3.ursala
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
lookup = -: (^/~& product^|/~& charval)*lsPrK0/weights alphabet
|
||||
iprod = sum:-0+ lookup*p/weights
|
||||
2
Task/SEDOLs/Ursala/sedols-4.ursala
Normal file
2
Task/SEDOLs/Ursala/sedols-4.ursala
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
lookups = (-:+ * ^/~&l product^|/charval ~&)* *-* -*weights alphabet
|
||||
iprod = sum:-0+ gang +^|(~&,~)*lNrXXK9 ^(~&,&h!)* lookups
|
||||
15
Task/SEDOLs/Ursala/sedols-5.ursala
Normal file
15
Task/SEDOLs/Ursala/sedols-5.ursala
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#show+
|
||||
|
||||
examples = ^T(~&,~&h+ %nP+ checksum)*t
|
||||
|
||||
-[
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT]-
|
||||
26
Task/SEDOLs/VBA/sedols.vba
Normal file
26
Task/SEDOLs/VBA/sedols.vba
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
Function getSedolCheckDigit(Input1)
|
||||
Dim mult(6) As Integer
|
||||
mult(1) = 1: mult(2) = 3: mult(3) = 1
|
||||
mult(4) = 7: mult(5) = 3: mult(6) = 9
|
||||
If Len(Input1) <> 6 Then
|
||||
getSedolCheckDigit = "Six chars only please"
|
||||
Exit Function
|
||||
End If
|
||||
Input1 = UCase(Input1)
|
||||
Total = 0
|
||||
For i = 1 To 6
|
||||
s1 = Mid(Input1, i, 1)
|
||||
If (s1 = "A") Or (s1 = "E") Or (s1 = "I") Or (s1 = "O") Or (s1 = "U") Then
|
||||
getSedolCheckDigit = "No vowels"
|
||||
Exit Function
|
||||
End If
|
||||
If (Asc(s1) >= 48) And (Asc(s1) <= 57) Then
|
||||
Total = Total + Val(s1) * mult(i)
|
||||
Else
|
||||
Total = Total + (Asc(s1) - 55) * mult(i)
|
||||
End If
|
||||
|
||||
Next i
|
||||
getSedolCheckDigit = Input1 + CStr((10 - (Total Mod 10)) Mod 10)
|
||||
|
||||
End Function
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue