2015-03-30 20 views
9

Haskell’de yeniyim ve standart olarak giriş yapmak için bir fonksiyon (gcd) uygulamaya çalışıyorum; bu satırlar birbirinden ayrılmış ve her satırda az veya çok iki sayı. İşte benim girdi örneğidir:Haskell - Bir fonksiyonun birden çok satıra uygulanmaya çalışılması

 
3 
10 4 
1 100 
288 240 

Şu anda her iki numaralarının başlığın içine her satırı kesiliyor, ama ben bu tupleları ayırmak ve onlara bir işlev nasıl uygulanacağını bulmaktan sorun yaşıyorum.

import Data.List 

main :: IO() 
main = do 
    n <- readLn :: IO Int 
    content <- getContents 
    let 
    points = map (\[x, y] -> (x, y)). map (map (read::String->Int)). map words. lines $ content 
    ans = gcd (fst points :: Int) (snd points :: Int) 
    print ans 

iki Bu yanıt için aramaya başlamak için iyi bir yer olarak herhangi bir bilgi çok takdir: İşte ben bugüne kadar ne var. Öğrenme Haskell öğreticisini okudum ve bu sorunla ilgili herhangi bir bilgi bulamadım.

+1

saf fonksiyonunu 'f :: String yazmayı deneyin -> girişiniz bir çizgi alır ve hesaplar Int', önce gcd. İkinci adımda bu işlevi "ana" içindeki girdiye uygulayın. Ayrıca Prelude'den “uncurry :: (a -> b -> c) -> ((a, b) -> c)' ye bakınız. – sjakobi

cevap

3

Oldukça yakınsınız. gcd'u aramadan önce bir tuple veya tupl listesine dönüştürmek için bir neden yoktur.

main = do 
    contents <- getContents 
    print $ map ((\[x,y] -> gcd (read x) (read y)) . words) . lines $ contents 

Tüm ilginç şeyler print ve contents arasındadır. lines, içeriği satırlara böler. map (...), işlevi her satıra uygular. words çizgiyi kelimelere böler. \[x,y] -> gcd (read x) (read y), iki dizenin bir listesiyle eşleşir (ve aksi halde bir hatayı atar - genel olarak iyi bir uygulama değil, bunun gibi basit bir program için iyi), bu dizeleri Integer s olarak okuyun ve GCD'lerini hesaplayın.

Tembel IO'dan yararlanmak istiyorsanız, her satırı girdikten sonra her bir sonucu yazdırmak için aşağıdaki gibi değiştirebilirsiniz.

main = do 
    contents <- getContents 
    mapM_ (print . (\[x,y] -> gcd (read x) (read y)) . words) . lines $ contents 
+0

Sadece tek bir sayıdaki girdiden oluşan ilk satırı atlamanız gerekir. – Yuuri

+0

Hızlı yanıtlar için herkese teşekkür ederiz. Bunun tam olarak ne yaptığını görüyorum ve ayrıca başlangıçta iri parçalara bakmak zorunda kalacağım. – midnightconman

0

Veya, bir daha zorunlu bir tarzda yapabilirsiniz:

import Control.Monad 

main = do 
    n <- readLn 
    replicateM_ n $ do 
     [x, y] <- (map read . words) `liftM` getLine 
     print $ gcd x y 
İlgili konular