import Test.QuickCheck import Data.List (elemIndices) f :: String -> [[Int]] f s=[[([n|(n,x)<-z,x==c,i<=n]++l)!!(2^j)|(i,c)<-z]|let l=length s:l;z=zip[0..]s,j<-[0..4]] basic :: String -> [[Int]] basic s = basic' s <$> [1, 2, 4, 8, 16] basic' :: String -> Int -> [Int] basic' s j = basic'' s j <$> [0..] `zip` s basic'' :: String -> Int -> (Int, Char) -> Int basic'' s j (i, c) = let indexes = elemIndices c s ++ repeat (length s) in (< i) `dropWhile` indexes !! j cases :: [(String, [[Int]], String)] cases = [ ("aakakakakka", parse "1 3 4 5 6 7 8 10 9 11 11 \n\ \ 3 5 6 7 8 10 9 11 11 11 11 \n\ \ 7 10 9 11 11 11 11 11 11 11 11 \n\ \ 11 11 11 11 11 11 11 11 11 11 11 \n\ \ 11 11 11 11 11 11 11 11 11 11 11", "AKAK"), ("sydgdtsfixuvhdgisifdyovjcgs", parse "6 20 4 14 13 27 16 18 15 27 27 22 27 19 25 17 26 27 27 27 27 27 27 27 27 27 27 \n\ \ 16 27 13 25 19 27 26 27 17 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 \n\ \ 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 \n\ \ 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 \n\ \ 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27", "SYDG"), ("qmorzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", parse "59 59 59 59 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 \n\ \ 59 59 59 59 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 59 \n\ \ 59 59 59 59 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 59 59 59 \n\ \ 59 59 59 59 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 59 59 59 59 59 59 59 \n\ \ 59 59 59 59 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59", "QMORZ") ] where parse = ((read @Int <$>) . words <$>) . lines testCase :: (Eq b) => (a -> b) -> (a, b, String) -> String testCase f (args, ans, name) = if ans == f args then "." else "Failed \"" ++ name ++ "\"" main :: IO () main = do print $ testCase f <$> cases quickCheck (\s -> basic s == f s)