CUSIP: Difference between revisions

1,586 bytes added ,  4 years ago
Add Swift
(Add Swift)
Line 2,327:
68389X1059 not valid.
68389x105 not valid.</pre>
 
=={{header|Swift}}==
 
<lang swift>struct CUSIP {
var value: String
 
private static let alphabet = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
 
init?(value: String) {
if value.count == 9 && String(value.last!) == CUSIP.checkDigit(cusipString: String(value.dropLast())) {
self.value = value
} else if value.count == 8, let checkDigit = CUSIP.checkDigit(cusipString: value) {
self.value = value + checkDigit
} else {
return nil
}
}
 
static func checkDigit(cusipString: String) -> String? {
guard cusipString.count == 8, cusipString.allSatisfy({ $0.isASCII }) else {
return nil
}
 
let sum = cusipString.uppercased().enumerated().reduce(0, {sum, pair in
let (i, char) = pair
var v: Int
 
switch char {
case "*":
v = 36
case "@":
v = 37
case "#":
v = 38
case _ where char.isNumber:
v = char.wholeNumberValue!
case _:
v = Int(char.asciiValue! - 65) + 10
}
 
if i & 1 == 1 {
v *= 2
}
 
return sum + (v / 10) + (v % 10)
})
 
return String((10 - (sum % 10)) % 10)
}
}
 
let testCases = [
"037833100",
"17275R102",
"38259P508",
"594918104",
"68389X106",
"68389X105"
]
 
for potentialCUSIP in testCases {
print("\(potentialCUSIP) -> ", terminator: "")
 
switch CUSIP(value: potentialCUSIP) {
case nil:
print("Invalid")
case _:
print("Valid")
}
}</lang>
 
{{out}}
 
<pre>037833100 -> Valid
17275R102 -> Valid
38259P508 -> Valid
594918104 -> Valid
68389X106 -> Invalid
68389X105 -> Valid</pre>
 
=={{header|Tcl}}==