Dropcaps
One more or less implicit sub-challenge is actually keeping the spaces. We should not trim spaces from both sides of the string, neither dedup spaces between words.
Haskell
If we use words
and unwords
to extract the words and then join them back into a single string, we end up trimming each word, therefore deduping the spaces.
We need some sort of more standard splitting.
Solution 1
import Data.Char (toLower, toUpper)
import Data.List (intercalate)
upcaseFirst :: [Char] -> [Char]
upcaseFirst "" = ""
upcaseFirst (c:cs) = toUpper c : map toLower cs
split :: Char -> String -> [String]
split c s = case rest of
[] -> [chunk]
_:rest -> chunk : split c rest
where (chunk, rest) = break (== c) s
dropCap :: String -> String
dropCap str = intercalate " " $ go [] (split ' ' str)
where
go :: [String] -> [String] -> [String]
go acc [] = acc
go acc (s : ss)
| length s >= 3 = upcaseFirst s : go acc ss
| otherwise = s : go acc ss
The upcaseFirst
and split
functions were created as helpers.
The go
inner function properly capitalizes the first char strings of \(\text{length} >= 3\).
At the very end, we apply intercalate " "
to the result of go
to turn the list of strings back into a single string.
split
keeps an empty string in place of each place it could split on space, which later when intercalate
comes into play, ends up adding back all the spaces from the original string.
Here’s how split
is working:
λ> split ' ' " abc de f "
["","","abc","de","","","f","",""]
Note how each whitespace is turned into a ""
empty string in the resulting array.
That is what allows intercalate later to reconstruct the string with the original spaces in place.