8

私はhaskellを学び始めたばかりであり、それは私が慣れているもの(Cスタイルの言語)とは大きく異なる考え方です。

とにかく、私が取り組んでいる1つの問題については、ユーザー入力を受け取る必要があります。それは形で来るでしょう

2
10
20

例えば。フォーマットは最初の行で、その後の行数を示します。私の最初の考えは、最初の行を読んでから、その回数だけループを実行することでした。これはHaskellです!私の知る限り、ループは不可能です。

次の考えは、入力の最初の行を使用して、リストに続く他のn個の数字を入力することでした。しかし、これをどのように行うかはわかりません。私がここにいるのは、それを理解するために何を検索するのかさえわからないからです。

これを行うための面倒な方法を教えてくれてありがとう。今のところ大変ですが、「悟りを開いた」人から絶賛されているので、自分で言語を学ぶのも悪くないと思います。

これは1回だけ正常に実行されるコードですが、最初の行に続く2行目からn行目ごとに1回実行する必要があります。

l n = (-1)^n/(2*(fromIntegral n)+1)
a m = sum [l n | n <- [0..(m-1)]]
main =
    do  b <- readLn
        print (a b)

(また、コードに他に改善できる点があるかどうかを聞きたいのですが、この特定のケースでは、可能な限り少ない文字数で問題を解決するための競争です。これ以上は取得したくありません。他の人が同じ問題の答えを検索しようとしている場合に固有です。)

編集:みんなの答えをありがとう。私は最終的に私がそれを望んでいたように振る舞う何かを手に入れました。後世のために、そのためのコードを以下に示します。悲しいことに、それが飛んでいる色でテストケースに合格したにもかかわらず、彼らがそれをテストした実際のデータは異なっていました、そして彼らが私に言うのは私が「間違った答え」を得たということだけです。このコードは「機能」しますが、正しい答えは得られません。

import Control.Monad
l n = (-1)^n/(2*(fromIntegral n)+1)
a m = sum [l n | n <- [0..(m-1)]]
main =
    do  b <- readLn
        s <- replicateM b readLn
        mapM_ print [a c | c <- s]
4

4 に答える 4

10

まず第一に、haskellでうまくループすることができます。それはいつも起こります。構文構造は必要ないので、構文構造はありません。

ほとんどの場合、一般的な汎用ループはライブラリに入れられます。この場合、必要なループは標準ライブラリのモジュールにありますControl.Monad。それはと呼ばれreplicateMます。型アノテーションがありますMonad m => Int -> m a -> m [a]。この署名をあなたのケースに特化させるために、それはタイプを持っているでしょうInt -> IO Int -> IO [Int]。最初の引数は、ループする回数です。2つ目は、各ループで実行するIOアクションです。関数の結果は、入力のリストを生成するIOアクションです。

したがってinputs <- replicateM b readLn、doブロックに追加すると、最初の入力行に続く入力行のinputs値を含む名前付きリストがスコープに配置されます。b次に、ソリューション関数をこれらの線にマッピングできます。

于 2013-02-03T00:41:27.563 に答える
7

カールの解決策は機能しますが、やや不透明です。あなたがそれを書きたいなら、あなたはこのようなことをすることができます:

readLines :: Int -> IO [Int]
readLines 0 = return []
readLines n = do
   x <- fmap read getLine
   rest <- readLines (n-1)
   return $ x : rest

readSomeNumberOfLines :: IO [Int]
readSomeNumberOfLines = do
   n <- fmap read getLine
   readLines n

ここで行っているreadLinesのは、基本的に明白な基本ケース(0個を読み取るには、空のリストを指定する)と再帰的ケース(n個を読み取る、1つを読み取る、次に他のn-1を読み取る)を定義しているということです。物事、そしてそれらを一緒に組み合わせる)。

于 2013-02-03T00:52:58.683 に答える
2

正確に何をしたいかはわかりませんが、整数nを読み取り、次に次のn行を整数として読み取るには、次のようにすることができます。

import Control.Monad

-- read n, then sum integers read from the next n lines
test = do n <- readLn
          xs <- replicateM n readLn
          return $ sum xs

もちろん、最後のreturn $ sum xsは実質的ではありません。それがなかった場合は、明示的な型アノテーションが必要になりtestます。

これらの機能のいずれかを理解していない場合は、それらをフーグルしてください。

于 2013-02-03T01:00:57.773 に答える
1

読み取る行数であるreadInput nwhereを作成できます。これを呼び出すと、毎回n1を再帰的に減算します。n私もHaskellの初心者なので、これは最善のアプローチではないかもしれません。ただし、それでも機能するはずです。

于 2013-02-03T00:46:09.593 に答える