You are viewing a single comment's thread. Return to all comments →
use this as pattern for IO:
main :: IO ()
main = do
n_temp <- getLine
let n = read n_temp :: Int
forM_ [1..n] $ \boh -> do
q_temp <- getLine
let q = read q_temp :: Int
rawInput <- getMultipleLines q
let input = [(read (words str !! 0) :: Int, read (words str !! 1) :: Int ) | str <- rawInput]
-- here starts your code
getMultipleLines :: Int -> IO [String]
| n <= 0 = return 
| otherwise = do
x <- getLine
xs <- getMultipleLines (n-1)
let ret = (x:xs)
It works with most input format of HackerRank:
Thx! This is helpful. All this IO stuff was getting pretty ugly :)
That's still ugly, IMO. Here's my runner:
readInt x = read x :: Int
main = putStr . unlines . run . (map readInt) . words =<< getContents
From run, you can just work with pure functions like the Haskell gods intended.
how do you know how many lines to read? In a situation where a user is inputting a variable set of inputs, would this work?
If you run this it will just ask for inputs forever.
also, I think that you don't need to define your own read if your run function has a definition run :: [Int] -> [String]
run :: [Int] -> [String]
HackerRank tells you all you need to know about the input, so it's a completely different situation from an arbitrary CLI. This approach works for the type of problems on this particular site, and for the typical use case where input comes from a terminating program or a file.
It actually won't run forever because of a handy thing called EOF.
Nice idea about the type sig, though.
how would you write
ms <- forM [1..n] $ const $ getLine
let d = M.fromList $ (\[x,y] -> (x,y)) . words <$> ms
on one line?
d <- M.fromList <$> map ((\[x,y] -> (x,y)) . words) <$> replicateM n getLine
I'm a Haskell newbie and reading input data is the most difficult part of the problem for me. I don't see where your code structures the input data into the "grouping" required in this task.
I mean, how is the function "run" (if I understood at least that part) supposed to get T, and then, for 1..T, the value of N and the list of (x,y) as required for this problem? (I understand that we could simply "skip" the initial T but then (until EOF is reached) definitely need to get the N in order to know how many lines (x,y) we must read -- where am I wrong?)
I'm keen to switch from imperative to functional programming, but as far as the "I/O" is concerned, the problem statement "there are T test cases and for each test case..." already contains the declarative "for". And I'd like to write a function that receives a vector of N pairs (x,y), but how to get there without doing "for i in 1..N: read [x, y] and append to the list L" ?