|
| 1 | +{-# LANGUAGE TupleSections #-} |
| 2 | + |
| 3 | +module SpeedOfLetters (speedify) where |
| 4 | + |
| 5 | +-- https://www.codewars.com/kata/5fc7caa854783c002196f2cb/train/haskell |
| 6 | + |
| 7 | +import Data.List (groupBy, sortOn) |
| 8 | +import Data.Maybe (fromJust, fromMaybe, isJust) |
| 9 | + |
| 10 | +speedify :: String -> String |
| 11 | +speedify = makeText . rebuildLetters |
| 12 | + |
| 13 | +makeText :: [(Int, Char)] -> String |
| 14 | +makeText = go 0 |
| 15 | + where |
| 16 | + go :: Int -> [(Int, Char)] -> String |
| 17 | + go _ [] = [] |
| 18 | + go index chars@((i, c) : xs) |
| 19 | + | i == index = c : go (index + 1) xs |
| 20 | + | i < index = go index xs |
| 21 | + | otherwise = ' ' : go (index + 1) chars |
| 22 | + |
| 23 | +rebuildLetters :: String -> [(Int, Char)] |
| 24 | +rebuildLetters = map last . groupOn fst . sortOn fst . zipWith (curry run) [0 ..] |
| 25 | + |
| 26 | +run :: (Int, Char) -> (Int, Char) |
| 27 | +run (index, c) = (,c) . (+ index) . lookupLetter $ c |
| 28 | + |
| 29 | +lookupLetter :: Char -> Int |
| 30 | +lookupLetter c |
| 31 | + | isJust mIndex = fromJust mIndex |
| 32 | + | otherwise = error "Letter not found" |
| 33 | + where |
| 34 | + mIndex = lookup c letterIndices |
| 35 | + |
| 36 | +letterIndices :: [(Char, Int)] |
| 37 | +letterIndices = zip ['A' .. 'Z'] [0 ..] |
| 38 | + |
| 39 | +groupOn :: (Eq b) => (a -> b) -> [a] -> [[a]] |
| 40 | +groupOn get = groupBy (\a b -> get a == get b) |
0 commit comments