Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,82 @@
|
|||
module ISINVerification2 where
|
||||
|
||||
import Data.Char (isUpper, isDigit, digitToInt)
|
||||
|
||||
verifyISIN :: String -> Bool
|
||||
verifyISIN isin =
|
||||
correctFormat isin && mod (oddsum + multiplied_even_sum) 10 == 0
|
||||
where
|
||||
reverted = reverse $ convertToNumber isin
|
||||
theOdds = fst $ collectOddandEven reverted
|
||||
theEvens = snd $ collectOddandEven reverted
|
||||
oddsum = sum $ map digitToInt theOdds
|
||||
multiplied_even_sum = addUpDigits $ map ((* 2) . digitToInt) theEvens
|
||||
|
||||
capitalLetters :: String
|
||||
capitalLetters = ['A','B' .. 'Z']
|
||||
|
||||
numbers :: String
|
||||
numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
|
||||
correctFormat :: String -> Bool
|
||||
correctFormat isin =
|
||||
(length isin == 12) &&
|
||||
all (`elem` capitalLetters) (take 2 isin) &&
|
||||
all (\c -> elem c capitalLetters || elem c numbers) (drop 2 $ take 11 isin) &&
|
||||
elem (last isin) numbers
|
||||
|
||||
convertToNumber :: String -> String
|
||||
convertToNumber = concatMap convert
|
||||
where
|
||||
convert :: Char -> String
|
||||
convert c =
|
||||
if isDigit c
|
||||
then show $ digitToInt c
|
||||
else show (fromEnum c - 55)
|
||||
|
||||
collectOddandEven :: String -> (String, String)
|
||||
collectOddandEven term
|
||||
| odd $ length term =
|
||||
( concat
|
||||
[ take 1 $ drop n term
|
||||
| n <- [0,2 .. length term - 1] ]
|
||||
, concat
|
||||
[ take 1 $ drop d term
|
||||
| d <- [1,3 .. length term - 2] ])
|
||||
| otherwise =
|
||||
( concat
|
||||
[ take 1 $ drop n term
|
||||
| n <- [0,2 .. length term - 2] ]
|
||||
, concat
|
||||
[ take 1 $ drop d term
|
||||
| d <- [1,3 .. length term - 1] ])
|
||||
|
||||
addUpDigits :: [Int] -> Int
|
||||
addUpDigits list =
|
||||
sum $
|
||||
map
|
||||
(\d ->
|
||||
if d > 9
|
||||
then sum $ map digitToInt $ show d
|
||||
else d)
|
||||
list
|
||||
|
||||
printSolution :: String -> IO ()
|
||||
printSolution str = do
|
||||
putStr $ str ++ " is"
|
||||
if verifyISIN str
|
||||
then putStrLn " valid"
|
||||
else putStrLn " not valid"
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let isinnumbers =
|
||||
[ "US0378331005"
|
||||
, "US0373831005"
|
||||
, "U50378331005"
|
||||
, "US03378331005"
|
||||
, "AU0000XVGZA3"
|
||||
, "AU0000VXGZA3"
|
||||
, "FR0000988040"
|
||||
]
|
||||
mapM_ printSolution isinnumbers
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import Control.Monad ((<=<))
|
||||
import Data.Bifunctor (first)
|
||||
import Data.List (foldl') -- '
|
||||
import qualified Data.Map as M
|
||||
import Data.Maybe (fromMaybe)
|
||||
|
||||
-------------------- VALID ISIN STRING -------------------
|
||||
|
||||
validISIN :: String -> Bool
|
||||
validISIN =
|
||||
(&&) . isinPattern
|
||||
<*> luhn . (show <=< stringInts)
|
||||
|
||||
isinPattern :: String -> Bool
|
||||
isinPattern s =
|
||||
12 == length s
|
||||
&& all (`elem` capitals) l
|
||||
&& all (`elem` (capitals <> digits)) m
|
||||
&& head r `elem` digits
|
||||
where
|
||||
[l, m, r] = bites s [2, 9, 1]
|
||||
|
||||
luhn :: String -> Bool
|
||||
luhn x = 0 == rem (s1 + s2) 10
|
||||
where
|
||||
odds = [(: []), const []]
|
||||
evens = reverse odds
|
||||
stream f =
|
||||
concat $
|
||||
zipWith ($) (cycle f) (stringInts $ reverse x)
|
||||
s1 = sum (stream odds)
|
||||
s2 =
|
||||
sum $
|
||||
sum . stringInts . show . (2 *) <$> stream evens
|
||||
|
||||
charMap :: M.Map Char Int
|
||||
charMap = M.fromList $ zip (digits <> capitals) [0 ..]
|
||||
|
||||
stringInts :: String -> [Int]
|
||||
stringInts = fromMaybe [] . traverse (`M.lookup` charMap)
|
||||
|
||||
bites :: [a] -> [Int] -> [[a]]
|
||||
bites xs =
|
||||
(reverse . fst)
|
||||
. foldl' -- '
|
||||
(\(a, r) x -> first (: a) (splitAt x r))
|
||||
([], xs)
|
||||
|
||||
capitals, digits :: String
|
||||
capitals = ['A' .. 'Z']
|
||||
digits = ['0' .. '9']
|
||||
|
||||
--------------------------- TEST -------------------------
|
||||
main :: IO ()
|
||||
main =
|
||||
mapM_
|
||||
(print . ((,) <*> validISIN))
|
||||
[ "US0378331005",
|
||||
"US0373831005",
|
||||
"U50378331005",
|
||||
"US03378331005",
|
||||
"AU0000XVGZA3",
|
||||
"AU0000VXGZA3",
|
||||
"FR0000988040"
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue