Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -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

View file

@ -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"
]