I got into using CodeForces a few weeks ago, using Haskell for the last two competitions. I spent hours debugging three Haskell quirks in the competitions, so I hope this saves time for future Haskellers!↵
↵
1. Do NOT use default `getContents` or `getLines` in CodeForces. I found that at least one of my solutions per competitions will TLE even if I have the perfect algorithm. The issue was not my algorithm, it was the I/O time. Switching to `getContents` or `getLines` from `Data.ByteString.Char8` fixed these issues.↵
↵
I usually do something like↵
↵
```hs↵
import qualified Data.ByteString.Char8 as BS↵
↵
main = do↵
n <- fst . fromJust . BS.getInt <$> BS.getLine↵
forM [1..n] $ \_ -> do↵
input <- BS.getLine↵
-- logic↵
```↵
↵
2. STRIP OUT '\r' from the end of the output of `Data.ByteString.Char8.getLine`. I spent hours trying to figure out why my one of my string-based algorithms worked on my laptop, but not CF. It turns out that newlines on CF are `\r\n`, while my MacBook uses just `\n`. Using `Data.ByteString.Char8.getLine` on CodeForces resulted in `\r` at the end of the line, which added an extra "\r" element in my strings on CF only.↵
↵
I usually do↵
↵
```↵
BS.filter (/= '\r') myByteString↵
```↵
↵
to strip the line. `BS.strip` does exist, but the version of byte string in the CF Haskell environment is outdated and does not have `BS.strip`.↵
↵
3. (less important) Unlike Python or C, Haskell does not have a built-in heap or priority queue implementation. It turns out that [ordered sets](https://hackage-content.haskell.org/package/containers-0.8/docs/Data-Set.html#g:14) will be close to what you want. The only issue is that sets can only hold distinct values, so if your heap will have multiple of the same elements, you need to store tuples of (value, iterationCount) in the set. The heap will first use `value` to order the heap, but if there are multiple of the same value it will use `iterationCount` to distinguish the values. https://hackage.haskell.org/package/heaps-0.4.1/docs/Data-Heap.html seems like a good heap implementation that would remove the need to add the `iterationCount` boilerplate, but understandably it is not part of the CF GHC environment.
↵
1. Do NOT use default `getContents` or `getLines` in CodeForces. I found that at least one of my solutions per competitions will TLE even if I have the perfect algorithm. The issue was not my algorithm, it was the I/O time. Switching to `getContents` or `getLines` from `Data.ByteString.Char8` fixed these issues.↵
↵
I usually do something like↵
↵
```hs↵
import qualified Data.ByteString.Char8 as BS↵
↵
main = do↵
n <- fst . fromJust . BS.getInt <$> BS.getLine↵
forM [1..n] $ \_ -> do↵
input <- BS.getLine↵
-- logic↵
```↵
↵
2. STRIP OUT '\r' from the end of the output of `Data.ByteString.Char8.getLine`. I spent hours trying to figure out why my one of my string-based algorithms worked on my laptop, but not CF. It turns out that newlines on CF are `\r\n`, while my MacBook uses just `\n`. Using `Data.ByteString.Char8.getLine` on CodeForces resulted in `\r` at the end of the line, which added an extra "\r" element in my strings on CF only.↵
↵
I usually do↵
↵
```↵
BS.filter (/= '\r') myByteString↵
```↵
↵
to strip the line. `BS.strip` does exist, but the version of byte string in the CF Haskell environment is outdated and does not have `BS.strip`.↵
↵
3. (less important) Unlike Python or C, Haskell does not have a built-in heap or priority queue implementation. It turns out that [ordered sets](https://hackage-content.haskell.org/package/containers-0.8/docs/Data-Set.html#g:14) will be close to what you want. The only issue is that sets can only hold distinct values, so if your heap will have multiple of the same elements, you need to store tuples of (value, iterationCount) in the set. The heap will first use `value` to order the heap, but if there are multiple of the same value it will use `iterationCount` to distinguish the values. https://hackage.haskell.org/package/heaps-0.4.1/docs/Data-Heap.html seems like a good heap implementation that would remove the need to add the `iterationCount` boilerplate, but understandably it is not part of the CF GHC environment.




