2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,6 +1,10 @@
|
|||
;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
|
||||
|
||||
That is, given this input:
|
||||
<pre>
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
|
|
@ -10,8 +14,11 @@ B0YBKL
|
|||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030</pre> Produce this output:
|
||||
<pre>7108899
|
||||
B00030
|
||||
</pre>
|
||||
Produce this output:
|
||||
<pre>
|
||||
7108899
|
||||
B0YBKJ7
|
||||
4065663
|
||||
B0YBLH2
|
||||
|
|
@ -21,8 +28,14 @@ B0YBKL9
|
|||
B0YBKR5
|
||||
5852842
|
||||
B0YBKT7
|
||||
B000300</pre>
|
||||
B000300
|
||||
</pre>
|
||||
|
||||
For extra credit, check each input is correctly formed, especially with respect to valid characters allowed in a SEDOL string.
|
||||
;Extra credit:
|
||||
Check each input is correctly formed, especially with respect to valid characters allowed in a SEDOL string.
|
||||
|
||||
C.f. [[Luhn test]], [[Calculate International Securities Identification Number|ISIN]]
|
||||
|
||||
;Related tasks:
|
||||
* [[Luhn test]]
|
||||
* [[Calculate International Securities Identification Number|ISIN]]
|
||||
<br><br>
|
||||
|
|
|
|||
43
Task/SEDOLs/Elixir/sedols.elixir
Normal file
43
Task/SEDOLs/Elixir/sedols.elixir
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
defmodule SEDOL do
|
||||
@sedol_char "0123456789BCDFGHJKLMNPQRSTVWXYZ" |> String.codepoints
|
||||
@sedolweight [1,3,1,7,3,9]
|
||||
|
||||
defp char2value(c) do
|
||||
unless c in @sedol_char, do: raise ArgumentError, "No vowels"
|
||||
String.to_integer(c,36)
|
||||
end
|
||||
|
||||
def checksum(sedol) do
|
||||
if String.length(sedol) != length(@sedolweight), do: raise ArgumentError, "Invalid length"
|
||||
sum = Enum.zip(String.codepoints(sedol), @sedolweight)
|
||||
|> Enum.map(fn {ch, weight} -> char2value(ch) * weight end)
|
||||
|> Enum.sum
|
||||
to_string(rem(10 - rem(sum, 10), 10))
|
||||
end
|
||||
end
|
||||
|
||||
data = ~w{
|
||||
710889
|
||||
B0YBKJ
|
||||
406566
|
||||
B0YBLH
|
||||
228276
|
||||
B0YBKL
|
||||
557910
|
||||
B0YBKR
|
||||
585284
|
||||
B0YBKT
|
||||
B00030
|
||||
C0000
|
||||
1234567
|
||||
00000A
|
||||
}
|
||||
|
||||
Enum.each(data, fn sedol ->
|
||||
:io.fwrite "~-8s ", [sedol]
|
||||
try do
|
||||
IO.puts sedol <> SEDOL.checksum(sedol)
|
||||
rescue
|
||||
e in ArgumentError -> IO.inspect e
|
||||
end
|
||||
end)
|
||||
|
|
@ -1 +1 @@
|
|||
ac1 =: (, 10 | 9 7 9 3 7 1 +/@:* ])&.(sn i. |:)
|
||||
ac2 =: (, 10 | 9 7 9 3 7 1 +/@:* ])&.(sn i. |:)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
ac2 =. (,"1 0 (841 $ '0987654321') {~ 1 3 1 7 3 9 +/ .*~ sn i. ])
|
||||
ac3 =: (,"1 0 (841 $ '0987654321') {~ 1 3 1 7 3 9 +/ .*~ sn i. ])
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ 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 %base36 = (flat 0..9, 'A'..'Z') »=>« ^36;
|
||||
my @weights = 1, 3, 1, 7, 3, 9;
|
||||
|
||||
my @vs = %base36{ $s.comb };
|
||||
|
|
|
|||
48
Task/SEDOLs/PowerShell/sedols.psh
Normal file
48
Task/SEDOLs/PowerShell/sedols.psh
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
function Add-SEDOLCheckDigit
|
||||
{
|
||||
Param ( # Validate input as six-digit SEDOL number
|
||||
[ValidatePattern( "^[0123456789bcdfghjklmnpqrstvwxyz]{6}$" )]
|
||||
[parameter ( Mandatory = $True ) ]
|
||||
[string]
|
||||
$SixDigitSEDOL )
|
||||
|
||||
# Convert to array of single character strings, using type char as an intermediary
|
||||
$SEDOL = [string[]][char[]]$SixDigitSEDOL
|
||||
|
||||
# Define place weights
|
||||
$Weight = @( 1, 3, 1, 7, 3, 9 )
|
||||
|
||||
# Define character values (implicit in 0-based location within string)
|
||||
$Characters = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
$CheckSum = 0
|
||||
|
||||
# For each digit, multiply the character value by the weight and add to check sum
|
||||
0..5 | ForEach { $CheckSum += $Characters.IndexOf( $SEDOL[$_].ToLower() ) * $Weight[$_] }
|
||||
|
||||
# Derive the check digit from the partial check sum
|
||||
$CheckDigit = ( 10 - $CheckSum % 10 ) % 10
|
||||
|
||||
# Return concatenated result
|
||||
return ( $SixDigitSEDOL + $CheckDigit )
|
||||
}
|
||||
|
||||
# Test
|
||||
$List = @(
|
||||
"710889"
|
||||
"B0YBKJ"
|
||||
"406566"
|
||||
"B0YBLH"
|
||||
"228276"
|
||||
"B0YBKL"
|
||||
"557910"
|
||||
"B0YBKR"
|
||||
"585284"
|
||||
"B0YBKT"
|
||||
"B00030"
|
||||
)
|
||||
|
||||
ForEach ( $PartialSEDOL in $List )
|
||||
{
|
||||
Add-SEDOLCheckDigit -SixDigitSEDOL $PartialSEDOL
|
||||
}
|
||||
|
|
@ -1,53 +1,42 @@
|
|||
/*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'
|
||||
/*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
|
||||
|
||||
@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*/
|
||||
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,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
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue