ふつうの haskellプログラミング読了&はじめてのhaskell
1週間ほど前に買ったふつけるを読み終えました。haskell 難しいと聞いてましたけど、かなりわかり易かったです。いや嘘つきましたすいません。後半、型クラスの説明のあたりからもうなにがなにやら、、、ややこしかった。けど、遅延評価がどんなもんかはわかりました。カリー化(部分適用)もわかったような気がします。モナドはよくわかりません。maybeモナドってたぶんモナドってこと?って感じ。
さてそんな状態のわたくしですが、金槌を持つ人にはなんでも釘に見える、という例え通り、さっそくhaskellでなんか書いてみたくなりました。で、ネットをさまよっていたところ、面白そうなネタを発見。
高校生以下を対象にしたプログラミングコンテストらしいです。問題をみてみたところ手頃な感じなのでやってみることに。問題は↓これ。
n 個の整数からなる数列 a1, a2, ..., anと正整数 k (1 ≦ k ≦ n) が与えられる.
このとき,連続して並ぶ k 個の整数の和 Si = ai+ai+1+...+ai+k−1 (1 ≦ i ≦ n−k+1) の最大値を出力するプログラムを作りなさい
http://www.ioi-jp.org/joi/2006/2007-ho-prob_and_sol/2007-ho.pdf
あとで haskell に書き換える事を意識しつつ、 とりあえず python で書いてみる。
def head(xs): return xs[0] def last(xs): return xs[-1:] def tail(xs): return xs[1:] def drop(n, xs): return xs[n:] def take(n, xs): return xs[:n] lines = open("input.txt").read().strip().split("\n") header = head(lines).split(" ") length = int(head(header)) k = int(last(header)) ns = map(int, tail(lines)) f = lambda x: sum(take(k, drop(x, ns))) print max(map(f, range(length - k + 1)))
さてこれを haskell で置き換えるわけですが、、、、。
なんかよくわからん意味不明なエラーと、型が違います、と言われまくって2時間かけてようやく動くものができました。かなり酷いコードな予感がしますが、初めて書いたhaskellのコードということでさらしておきます。
import Data.Char main = do cs <- readFile "input.txt" let (length, k) = header cs ns = map strToInt (tail $ lines cs) print $ maximum $ map (f ns k) [0..(length-k)] f :: [Int] -> Int -> Int -> Int f ns k x = sum $ take k $ drop x ns header :: String -> (Int, Int) header xs = let (ys, zs) = break (isSpace) $ head $ lines xs in (strToInt ys, strToInt $ tail zs) strToInt :: String -> Int strToInt s = read s :: Int
こういうことすると、あとで見直したとき恥ずかしさのあまり自殺したくなるんだよね、、、しないけど。