RosettaCodeData/Task/SEDOLs/Factor/sedols.factor

43 lines
1.1 KiB
Factor

USING: combinators combinators.short-circuit formatting io kernel
math math.parser regexp sequences unicode ;
IN: rosetta-code.sedols
<PRIVATE
CONSTANT: input {
"710889" "B0YBKJ" "406566" "B0YBLH" "228276" "B0YBKL"
"557910" "B0YBKR" "585284" "B0YBKT" "B00030" "AEIOUA"
"123" "" "B_7K90"
}
CONSTANT: weights B{ 1 3 1 7 3 9 1 }
: sedol-error ( seq -- err-str )
{
{ [ dup empty? ] [ drop "no data" ] }
{ [ dup length 6 = not ] [ drop "invalid length" ] }
[ drop "invalid char(s)" ]
} cond "*error* " prepend ;
: sedol-valid? ( seq -- ? )
{ [ length 6 = ] [ R/ [0-9BCDFGHJ-NP-TV-Z]+/ matches? ] } 1&& ;
: sedol-value ( m -- n ) dup digit? [ digit> ] [ 55 - ] if ;
: sedol-checksum ( seq -- n )
[ sedol-value ] { } map-as weights [ * ] 2map sum ;
: (sedol-check-digit) ( seq -- str )
sedol-checksum 10 mod 10 swap - 10 mod number>string ;
PRIVATE>
: sedol-check-digit ( seq -- str )
dup sedol-valid? [ (sedol-check-digit) ] [ sedol-error ] if ;
: sedol-demo ( -- )
"SEDOL Check digit\n====== ===========" print
input [ dup sedol-check-digit "%-6s %s\n" printf ] each ;
MAIN: sedol-demo