CUSIP: Difference between revisions

Content added Content deleted
(Add Swift)
Line 2,327: Line 2,327:
68389X1059 not valid.
68389X1059 not valid.
68389x105 not valid.</pre>
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}}==
=={{header|Tcl}}==