RosettaCodeData/Task/CUSIP/D/cusip.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`