他学の「プログラミング序論」の課題をhaskellで解いてみた
三学期に入ってエ学システム学類(略称エシス)の授業を入れてみた。
実を言えば自由単位はすでに余ってるのだが、まぁ、「A率確保のため」と言うことにしておこう。
にしても暇な授業だった。
だったので課題をhaskellってみた。
ポインタのポインタについて。らしい。
課題はなんか引数処理がメインだけど。
まぁargvはchar**だし...。
課題1-1 : 引数を表示する
こんなの
$ ./a.out hoge fuga hoge fuga $
こうなった
import System main = do args <- getArgs sequence $ map putStrLn args
putStrLnをmapしてもdoしないとアクションが起こらない。
ということでsequence。
do使わないとこんな感じ?
import System main = getArgs >>= sequence . (map putStrLn)
">>="の使い方とかIO周りは苦手だなぁ...。
課題1-2 : 引数の総文字数を表示する
こんなの
$ ./a.out a ab abc 6 $
こうなった
import System main = do args <- getArgs print $ length $ concat args
課題見てまず思い浮かんだのが、Cでなくhaskellというね。
なんというかhaskellが完全に最近のマイブームになってる
Cで書くよりconcatしてlengthした方が楽。とか思ってしまう。
ちなみにC言語のargvは[0]が実行ファイル名だからtailが必要。
同様にdo無しで。
import System main = getArgs >>= print . length . concat
課題1-3 : 引数のうちオプション('-'で始まるもの)の個数をそれぞれ数える
こんなの
$ ./a.out -ivh -w -w hoge -vABC A:1 B:1 C:1 h:1 i:1 v:2 w:2 $
オプションは結合できるという条件らしい。
つまり"-hoge" = "-h -o -g -e"
少し悩んだがこうなった
import System import List main :: IO () main = do args <- getArgs printTuple $ countToTuple $ sort $ concat $ map optionFilter args where optionFilter ('-':xs) = xs optionFilter _ = [] countToTuple :: (Eq a) => [a] -> [(a,Int)] countToTuple [] = [] countToTuple xs@(x:_) = (x,length ys) : countToTuple zs where (ys,zs) = partition (== x) xs printTuple :: [(Char,Int)] -> IO () printTuple [] = return () printTuple ((x,y):xys) = do putStr (x:":") print y printTuple xys
ちと汚いが勘弁です。
countToTuple:: (Eq a) => [a] -> [(a,Int)]はPreludeとかList.にありそうな気がするんだがなぁ...
まぁ、命名センスが無いのは置いておいてくださいな。
とりあえず流れとしては引数のうち'-'で始まるやつは'-'抜いて、それ以外は完全無視して、concat。
で、そいつを相手にそれぞれの文字を数える、と言った感じ。
doなしはmainのとこを"getArgs >>="にしてs/\$/./gすればいいので割愛。
リスト相手だとhaskell「まじやべぇ」くらいに使える。
まじやべぇ。
#あは。タプルのスペル間違えてたw
#訂正 2007/12/10