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
$ content
Offline
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 =<< getContents
Offline
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
$ content
Offline
Thanks for modifying your program again in order to clarify me about my question
Offline