Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

3
Task/SEDOLs/00-META.yaml Normal file
View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/SEDOLs
note: Checksums

42
Task/SEDOLs/00-TASK.txt Normal file
View 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:
* &nbsp; [[Luhn test]]
* &nbsp; [[Calculate International Securities Identification Number|ISIN]]
<br><br>

View 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(sedolchecksum(sedol))

View 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
)

View 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.

View 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
}
}

View 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

View 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");

View 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;

View 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

View file

@ -0,0 +1,11 @@
"7108899
B0YBKJ7
4065663
B0YBLH2
2282765
B0YBKL9
5579107
B0YBKR5
5852842
B0YBKT7
B000300"

View 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]

View 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)
}

View 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)
}

View 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

View 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)

View 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;
}

View 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
View 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;
}

View 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.

View 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)))

View 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
View 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
View 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
View 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);
}

View 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
View 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()))
}

View 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)

View 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"
)
)

View file

@ -0,0 +1,10 @@
ELEM
=LAMBDA(x,
LAMBDA(xs,
ISNUMBER(MATCH(x, xs, 0))
)
)
MUL
=LAMBDA(a, LAMBDA(b, a * b))

View 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

View 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

View 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

View 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

View 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

View 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
View 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)
}
}
}

View 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) }

View 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()
}

View 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"
]

View 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
View 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
View file

@ -0,0 +1 @@
ac1 =: (, 10 | (10 - 1 3 1 7 3 9) +/@:* ])&.(sn i. |:)

1
Task/SEDOLs/J/sedols-3.j Normal file
View file

@ -0,0 +1 @@
ac2 =: (, 10 | 9 7 9 3 7 1 +/@:* ])&.(sn i. |:)

1
Task/SEDOLs/J/sedols-4.j Normal file
View file

@ -0,0 +1 @@
ac3 =: (,"1 0 (841 $ '0987654321') {~ 1 3 1 7 3 9 +/ .*~ sn i. ])

View 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].*?");
}
}

View 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);
}
}

View 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
View 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

View 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

View 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)}")
}

View 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;)"}
}
}

View 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
View 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])

View 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)

View 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"}]

View 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').

View 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.

View 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)

View 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" ]

View 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 ;

View 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";

View 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;

View 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.

View 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";
}

View 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>
<!--

View 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

View 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)) )

View 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
.

View 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
}

View 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

View 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)

View 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
View 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")

View 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
View 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)

View 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

View 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))))

View 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
>;

View 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

View 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

View 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());
}
}

View 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 @

View 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
}

View 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;

View 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);
}

View file

@ -0,0 +1,6 @@
String extend [
includesAnyOf: aSet [
aSet do: [ :e | (self includes: e) ifTrue: [ ^true ] ].
^false
]
].

View 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)
]
]
].

View 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 ]

View 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))
].

View 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" ];

View 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

View 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
}

View 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

View 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

View file

@ -0,0 +1,2 @@
weights = difference/*10 <1,3,1,7,3,9>
checksum = remainder\10+ iprod

View file

@ -0,0 +1,2 @@
lookup = -: (^/~& product^|/~& charval)*lsPrK0/weights alphabet
iprod = sum:-0+ lookup*p/weights

View file

@ -0,0 +1,2 @@
lookups = (-:+ * ^/~&l product^|/charval ~&)* *-* -*weights alphabet
iprod = sum:-0+ gang +^|(~&,~)*lNrXXK9 ^(~&,&h!)* lookups

View file

@ -0,0 +1,15 @@
#show+
examples = ^T(~&,~&h+ %nP+ checksum)*t
-[
710889
B0YBKJ
406566
B0YBLH
228276
B0YBKL
557910
B0YBKR
585284
B0YBKT]-

View 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