You are not logged in.
Hello,
I'm an experienced C/C++ programmer and I would like to use Haskell to solve some problems.
But it is hard to me to write a simple way to read input from a file and analyze it, so I ask you how to do this. I didn't find how to do this around google or this forum, that's why I came to here.
Suppose we are given this problem:
"We're analyzing numbers and we want to know which numbers are even. The input consists on a number, N, and then N lines which contain a single integer. You are to say what numbers are even."
INPUT EXAMPLE:
3
1234
5555555
123044390581349287182
OUTPUT EXAMPLE:
yes
no
yes
I wrote the module that returns a string depending on if the number is even or not... But I would like to know how to repeat that function for N numbers. I don't want a superoptimized way or a strange way, I just want a simple and readable one...
In C++ i would do:
for (int i = 0; i < cases; i++)
{
cin >> number;
cout << analyze(number) << endl; // analyze returns a string
}Can you iluminate with your knowledge, archers? ![]()
Thank you.
Offline
Offline
Sorry, but I didn't want that, I read the first results for that search and I know how to get the input, but have no idea to solve the sample problem.
In the example above, I want to apply the funcion N times, i don't want a "while" style loop.
Offline
you'd probably want to put the lines of the file (the numbers) into a list, then map a simple odd/even check on that list creating a new list of yes/no's. then just print `take N $ thatList`. if you set it up right, haskell's laziness will only evaluate the map N times.
Last edited by brisbin33 (2010-05-10 13:57:02)
//github/
Offline
Try this if you're still having trouble
module Main where
import System.IO
main = do
let test x = if even (read x) then "yes" else "no"
withFile "test" ReadMode $ \handle -> do
content <- hGetContents handle
mapM_ ( putStrLn . test )
. drop 1 -- first line is pointless
. lines
$ contentOffline
I'd like more pure functions.
module Main where
act :: [Int] -> [String]
act (l:xs) = map test $ take l xs
where
test x | even x = "yes"
| otherwise = "no"
act _ = error "no input"
main :: IO ()
main = putStr . unlines . act . map read . lines =<< getContentsOffline
Thanks for the posts!
However, it looks like you need to get involved a lot in this language to solve problems like that. I looked that dvolk's script would compute all numbers, and not the first N numbers.
jxy posted a nice algorithm, but I can't understand it at all because of that operator (=<<).
I was thinking about this language and I agree it's very good and readable, but I don't like the way to solve these kinds of simple problems so "forced".
Thanks for all the reaplies except the first one ![]()
Salut!
Offline
Well, you said that the first line has the number N, followed by N lines. Given your description the program would always test the whole file.
If you have a file with X lines and you'd only like to test N <= X lines, this should do it:
module Main where
import System.IO
import Control.Applicative
main = do
let test x = if even (read x) then "yes" else "no"
withFile "test" ReadMode $ \handle -> do
nlines <- read <$> hGetLine handle
content <- hGetContents handle
mapM_ ( putStrLn . test )
. take nlines
. lines
$ contentOffline
Thanks for modifying your program again in order to clarify me about my question ![]()
Offline