import Data.Char (isAsciiUpper, isDigit, ord)



checkSum :: String -> String
checkSum x =
  case traverse sedolValue x of
    Right xs -> (show . checkSumFromSedolValues) xs
    Left annotated -> annotated

checkSumFromSedolValues :: [Int] -> Int
checkSumFromSedolValues xs =
  rem
    ( 10
        - rem
          ( sum $
              zipWith
                (*)
                [1, 3, 1, 7, 3, 9]
                xs
          )
          10
    )
    10

sedolValue :: Char -> Either String Int
sedolValue c
  | c `elem` "AEIOU" = Left "  Unexpected vowel."
  | isDigit c = Right (ord c - ord '0')
  | isAsciiUpper c = Right (ord c - ord 'A' + 10)


main :: IO ()
main =
  mapM_
    (putStrLn . ((<>) <*> checkSum))
    [ "710889",
      "B0YBKJ",
      "406566",
      "B0YBLH",
      "228276",
      "B0YBKL",
      "557910",
      "B0YBKR",
      "585284",
      "B0YBKT",
      "BOYBKT", 
      "B00030"
    ]