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!
- Do NOT use default
getContentsorgetLinesin 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 togetContentsorgetLinesfromData.ByteString.Char8fixed these issues.
I usually do something like
import qualified Data.ByteString.Char8 as BS
main = do
n <- fst . fromJust . BS.readInt <$> BS.getLine
forM [1..n] $ \_ -> do
input <- BS.getLine
-- logic
- STRIP OUT
'\r'from the end of the output ofData.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. UsingData.ByteString.Char8.getLineon CodeForces resulted in\rat 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.
- (less important) Unlike Python or C, Haskell does not have a built-in heap or priority queue implementation. It turns out that ordered sets 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 usevalueto order the heap, but if there are multiple of the same value it will useiterationCountto 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 theiterationCountboilerplate, but understandably it is not part of the CF GHC environment.



