tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
28
Task/SEDOLs/0DESCRIPTION
Normal file
28
Task/SEDOLs/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
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>
|
||||
|
||||
For extra credit, check each input is correctly formed, especially with respect to valid characters allowed in a SEDOL string.
|
||||
|
||||
C.f. [[Luhn test]]
|
||||
2
Task/SEDOLs/1META.yaml
Normal file
2
Task/SEDOLs/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Checksums
|
||||
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
|
||||
)
|
||||
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
|
||||
}
|
||||
}
|
||||
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;
|
||||
17
Task/SEDOLs/AutoHotkey/sedols.ahk
Normal file
17
Task/SEDOLs/AutoHotkey/sedols.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 w1:=1,w2:=3,w3:=1,w4:=7,w5:=3,w6:=9
|
||||
Loop Parse, w
|
||||
s += ((c:=Asc(A_LoopField))>=Asc("A") ? c-Asc("A")+10 : c-Asc("0")) * w%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.bbc
Normal file
21
Task/SEDOLs/BBC-BASIC/sedols.bbc
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)
|
||||
52
Task/SEDOLs/C++/sedols.cpp
Normal file
52
Task/SEDOLs/C++/sedols.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#include <numeric>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const int weights[] = {1,3,1,7,3,9};
|
||||
const string valid_chars = "BCDFGHJKLMNPQRSTVWXYZ0123456789";
|
||||
|
||||
int char_value(char c){ return isalpha(c) ? c -'A' + 10 : c - '0'; }
|
||||
|
||||
int sedol_checksum(string const& sedol)
|
||||
{
|
||||
//Check contents
|
||||
if(sedol.size() != 6)
|
||||
throw length_error("length of sedol string != 6");
|
||||
if(sedol.find_first_not_of(valid_chars) != std::string::npos)
|
||||
throw invalid_argument("sedol string contains disallowed characters");
|
||||
|
||||
vector<int> char_values;
|
||||
transform(sedol.begin(), sedol.end(), back_inserter(char_values), char_value);
|
||||
const int weighted_sum = inner_product(char_values.begin(), char_values.end(), weights, 0);
|
||||
return (10 - (weighted_sum % 10)) % 10;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string inputs[] = {
|
||||
"710889",
|
||||
"B0YBKJ",
|
||||
"406566",
|
||||
"B0YBLH",
|
||||
"228276",
|
||||
"B0YBKL",
|
||||
"557910",
|
||||
"B0YBKR",
|
||||
"585284",
|
||||
"B0YBKT",
|
||||
"B00030"
|
||||
};
|
||||
const size_t n_inputs = sizeof(inputs) / sizeof(*inputs);
|
||||
|
||||
for(size_t i = 0; i != n_inputs; ++i)
|
||||
{
|
||||
cout << inputs[i] << sedol_checksum(inputs[i]) << "\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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)
|
||||
in {
|
||||
assert(sedol.length == 6);
|
||||
foreach (c; sedol)
|
||||
assert(isDigit(c) || (isUpper(c) && !canFind("AEIOU", c)));
|
||||
} out (result) {
|
||||
assert(isDigit(result));
|
||||
} body {
|
||||
static int c2v(in dchar c){ return isDigit(c) ? c-'0' : c-'A'+10; }
|
||||
immutable int d = sedol.map!c2v().dotProduct([1,3,1,7,3,9]);
|
||||
return '0' + 10 - (d % 10);
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (sedol; "710889 B0YBKJ 406566 B0YBLH 228276
|
||||
B0YBKL 557910 B0YBKR 585284 B0YBKT".split())
|
||||
writeln(sedol, checksum(sedol));
|
||||
}
|
||||
35
Task/SEDOLs/D/sedols-2.d
Normal file
35
Task/SEDOLs/D/sedols-2.d
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import std.stdio, std.algorithm, std.string, std.numeric, std.ascii;
|
||||
|
||||
char sedolChecksum(in char[] sedol) /*pure*/ nothrow
|
||||
in {
|
||||
assert(sedol.length == 6, "SEDOL must be 6 chars long.");
|
||||
enum uint mask = 0b11_1110_1111_1011_1110_1110_1110;
|
||||
|
||||
foreach (c; sedol)
|
||||
assert(isDigit(c) ||
|
||||
(c > 'A' && c <= 'Z' && ((1U << (c - 'A')) & mask)),
|
||||
"SEDOL with wrong char.");
|
||||
} out(result) {
|
||||
assert(isDigit(result));
|
||||
static int c2v(in dchar c){ return isDigit(c) ? 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 {
|
||||
enum int[] weights = [1, 3, 1, 7, 3, 9];
|
||||
|
||||
int sum = 0;
|
||||
foreach (i, c; sedol) {
|
||||
if (isDigit(c))
|
||||
sum += (c - '0') * weights[i];
|
||||
else
|
||||
sum += (c - 'A' + 10) * weights[i];
|
||||
}
|
||||
|
||||
return '0' + 10 - (sum % 10);
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (s; ["710889", "B0YBKJ", "406566", "B0YBLH", "228276",
|
||||
"B0YBKL", "557910", "B0YBKR", "585284", "B0YBKT"])
|
||||
writeln(s, s.sedolChecksum());
|
||||
}
|
||||
12
Task/SEDOLs/D/sedols-3.d
Normal file
12
Task/SEDOLs/D/sedols-3.d
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import std.stdio, std.algorithm, std.string, std.numeric;
|
||||
|
||||
auto checksum(string s) {
|
||||
auto m = s.map!q{ a>='0' && a<='9' ? a-'0' : a-'A'+10 }();
|
||||
return '0' + 10 - m.dotProduct([1,3,1,7,3,9]) % 10;
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (sedol; "710889 B0YBKJ 406566 B0YBLH 228276
|
||||
B0YBKL 557910 B0YBKR 585284 B0YBKT".split())
|
||||
writeln(sedol, sedol.checksum());
|
||||
}
|
||||
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()))
|
||||
}
|
||||
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
|
||||
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()
|
||||
}
|
||||
22
Task/SEDOLs/Haskell/sedols.hs
Normal file
22
Task/SEDOLs/Haskell/sedols.hs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import Data.Char
|
||||
|
||||
char2value c | c `elem` "AEIOU" = error "No vowels."
|
||||
| c >= '0' && c <= '9' = ord c - ord '0'
|
||||
| c >= 'A' && c <= 'Z' = ord c - ord 'A' + 10
|
||||
|
||||
sedolweight = [1,3,1,7,3,9]
|
||||
|
||||
checksum sedol = show ((10 - (tmp `mod` 10)) `mod` 10)
|
||||
where tmp = sum $ zipWith (*) sedolweight $ map char2value sedol
|
||||
|
||||
main = mapM_ (\sedol -> putStrLn $ sedol ++ checksum sedol)
|
||||
[ "710889",
|
||||
"B0YBKJ",
|
||||
"406566",
|
||||
"B0YBLH",
|
||||
"228276",
|
||||
"B0YBKL",
|
||||
"557910",
|
||||
"B0YBKR",
|
||||
"585284",
|
||||
"B0YBKT" ]
|
||||
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 @@
|
|||
ac1 =: (, 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 @@
|
|||
ac2 =. (,"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.js
Normal file
41
Task/SEDOLs/JavaScript/sedols.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);
|
||||
}
|
||||
}
|
||||
31
Task/SEDOLs/Liberty-BASIC/sedols.liberty
Normal file
31
Task/SEDOLs/Liberty-BASIC/sedols.liberty
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)
|
||||
19
Task/SEDOLs/Mathematica/sedols.math
Normal file
19
Task/SEDOLs/Mathematica/sedols.math
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
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"}]
|
||||
|
||||
->Output:
|
||||
7108899
|
||||
B0YBKJ7
|
||||
4065663
|
||||
B0YBLH2
|
||||
2282765
|
||||
B0YBKL9
|
||||
5579107
|
||||
B0YBKR5
|
||||
5852842
|
||||
B0YBKT7
|
||||
B0003010
|
||||
SEDOL[DUMMY] -> rejected
|
||||
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('O').
|
||||
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.
|
||||
29
Task/SEDOLs/OCaml/sedols.ocaml
Normal file
29
Task/SEDOLs/OCaml/sedols.ocaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
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
|
||||
|
||||
let sedolweight = [1;3;1;7;3;9]
|
||||
|
||||
let explode s =
|
||||
let result = ref [] in
|
||||
String.iter (fun c -> result := c :: !result) s;
|
||||
List.rev !result
|
||||
|
||||
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" ]
|
||||
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.pascal
Normal file
45
Task/SEDOLs/Pascal/sedols.pascal
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-6/sedols.pl6
Normal file
26
Task/SEDOLs/Perl-6/sedols.pl6
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 = ( 0..9, 'A'..'Z' ) 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
|
||||
>;
|
||||
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(&\@\@) {
|
||||
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 sedol($) {
|
||||
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";
|
||||
}
|
||||
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)) )
|
||||
40
Task/SEDOLs/PureBasic/sedols.purebasic
Normal file
40
Task/SEDOLs/PureBasic/sedols.purebasic
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.py
Normal file
25
Task/SEDOLs/Python/sedols.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)
|
||||
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)
|
||||
53
Task/SEDOLs/REXX/sedols.rexx
Normal file
53
Task/SEDOLs/REXX/sedols.rexx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*REXX program computes the check (last) digit for 6 or 7 char SEDOLs.*/
|
||||
/*if the SEDOL is 6 characters, */
|
||||
/*a check digit is added. */
|
||||
|
||||
/*if the SEDOL is 7 characters, a */
|
||||
/*check digit is created and it is*/
|
||||
/*verified that it's equal to the */
|
||||
/*check digit already on the SEDOL*/
|
||||
@.=
|
||||
arg @.1 . /*allow a user-specified SEDOL. */
|
||||
if @.1=='' then do /*if none, then assume 11 defaults*/
|
||||
@.1 = 710889
|
||||
@.2 ='B0YBKJ'
|
||||
@.3 = 406566
|
||||
@.4 ='B0YBLH'
|
||||
@.5 = 228276
|
||||
@.6 ='B0YBKL'
|
||||
@.7 = 557910
|
||||
@.8 ='B0YBKR'
|
||||
@.9 = 585284
|
||||
@.10='B0YBKT'
|
||||
@.11='B00030'
|
||||
end
|
||||
|
||||
@abcU='ABCDEFGHIJKLMNOPQRSTUVWXYZ' /*the uppercase Latin alphabet. */
|
||||
alphaDigs='0123456789'@abcU /*legal chars, and then some. */
|
||||
allowable=space(translate(alphaDigs,,'AEIOU'),0) /*remove the vowels.*/
|
||||
weights=1317391 /*various weights for SEDOL chars*/
|
||||
/*an alternative would be to use:*/
|
||||
/* weights='1 3 1 7 3 9 1' if */
|
||||
/*any weights were greater than 9*/
|
||||
do j=1 while @.j\==''; sedol=@.j /*process each specified SEDOL. */
|
||||
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 /*checkDigit sum (so far). */
|
||||
do k=1 for 6 /*process each character in 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,9) 'SEDOL + check digit:' left(sedol,6)chkDig
|
||||
end /*j*/
|
||||
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*─────────────────────────────────────subroutines──────────────────────*/
|
||||
sed: say; say 'SEDOL:' sedol; say; return
|
||||
ser: say; say '*** error! ***'; say; say 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))))
|
||||
28
Task/SEDOLs/Ruby/sedols.rb
Normal file
28
Task/SEDOLs/Ruby/sedols.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
def char2value(c)
|
||||
raise "No vowels" if 'AEIOU'.include?(c)
|
||||
c.to_i(36)
|
||||
end
|
||||
|
||||
Sedolweight = [1,3,1,7,3,9]
|
||||
|
||||
def checksum(sedol)
|
||||
tmp = sedol.split('').zip(Sedolweight).map { |ch, weight|
|
||||
char2value(ch) * weight }.inject(0) { |sum, x|
|
||||
sum + x }
|
||||
((10 - (tmp % 10)) % 10).to_s
|
||||
end
|
||||
|
||||
for sedol in %w{
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
}
|
||||
puts sedol + checksum(sedol)
|
||||
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;
|
||||
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 ]
|
||||
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.tuscript
Normal file
20
Task/SEDOLs/TUSCRIPT/sedols.tuscript
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
|
||||
}
|
||||
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]-
|
||||
Loading…
Add table
Add a link
Reference in a new issue