100 lines
2.3 KiB
D
100 lines
2.3 KiB
D
import std.stdio;
|
|
|
|
void main(string[] args) {
|
|
writeln("CUSIP Verdict");
|
|
foreach(arg; args[1..$]) {
|
|
writefln("%9s : %s", arg, isValidCusip(arg) ? "Valid" : "Invalid");
|
|
}
|
|
}
|
|
|
|
class IllegalCharacterException : Exception {
|
|
this(string msg) {
|
|
super(msg);
|
|
}
|
|
}
|
|
|
|
bool isValidCusip(string cusip) in {
|
|
assert(cusip.length == 9, "Incorrect cusip length");
|
|
} body {
|
|
try {
|
|
auto check = cusipCheckDigit(cusip);
|
|
return cusip[8] == ('0' + check);
|
|
} catch (IllegalCharacterException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
unittest {
|
|
// Oracle Corporation
|
|
assertEquals(isValidCusip("68389X105"), true);
|
|
|
|
// Oracle Corporation (invalid)
|
|
assertEquals(isValidCusip("68389X106"), false);
|
|
}
|
|
|
|
int cusipCheckDigit(string cusip) in {
|
|
assert(cusip.length == 9, "Incorrect cusip length");
|
|
} body {
|
|
int sum;
|
|
for (int i=0; i<8; ++i) {
|
|
char c = cusip[i];
|
|
int v;
|
|
|
|
switch(c) {
|
|
case '0': .. case '9':
|
|
v = c - '0';
|
|
break;
|
|
case 'A': .. case 'Z':
|
|
v = c - 'A' + 10;
|
|
break;
|
|
case '*':
|
|
v = 36;
|
|
break;
|
|
case '@':
|
|
v = 37;
|
|
break;
|
|
case '#':
|
|
v = 38;
|
|
break;
|
|
default:
|
|
throw new IllegalCharacterException("Saw character: " ~ c);
|
|
}
|
|
if (i%2 == 1) {
|
|
v = 2 * v;
|
|
}
|
|
|
|
sum = sum + (v / 10) + (v % 10);
|
|
}
|
|
|
|
return (10 - (sum % 10)) % 10;
|
|
}
|
|
|
|
unittest {
|
|
// Apple Incorporated
|
|
assertEquals(cusipCheckDigit("037833100"), 0);
|
|
|
|
// Cisco Systems
|
|
assertEquals(cusipCheckDigit("17275R102"), 2);
|
|
|
|
// Google Incorporated
|
|
assertEquals(cusipCheckDigit("38259P508"), 8);
|
|
|
|
// Microsoft Corporation
|
|
assertEquals(cusipCheckDigit("594918104"), 4);
|
|
|
|
// Oracle Corporation
|
|
assertEquals(cusipCheckDigit("68389X105"), 5);
|
|
}
|
|
|
|
version(unittest) {
|
|
void assertEquals(T)(T actual, T expected) {
|
|
import core.exception;
|
|
import std.conv;
|
|
if (actual != expected) {
|
|
throw new AssertError("Actual [" ~ to!string(actual) ~ "]; Expected [" ~ to!string(expected) ~ "]");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Invoke with `cusip 037833100 17275R102 38259P508 594918104 68389X106 68389X105`
|