プログラマとプロマネのあいだ

プログラマもやるし、プロマネもやるし、たまに似非アーキとか営業っぽいこともやるITエンジニアがスキルアップの話を中心に日常を綴るブログです。

Haskell

「Ansi Common Lisp」9章練習問題 - Haskell版

1. 実数のリストを引数として、このリストが降順でない並びになっている場合に真を返す関数を定義せよ。 isDescendingOrder :: [Double] -> Bool isDescendingOrder [] = False isDescendingOrder (x:[]) = True isDescendingOrder (x:xs) = if x > (head xs…

「Ansi Common Lisp」7章練習問題 - Haskell版

1. ファイル名を引数として、ファイルの各行を構成するストリングをリストとして返す関数を定義せよ。 うーん、相変わらずモナド分からん。。 近いものはできた。 import IO fileToStrLine :: String -> IO () fileToStrLine fileName = do handle <- openFi…

「Ansi Common Lisp」6章練習問題 - Haskell版

3. 任意の数の引数をとり、その引数の個数を返す関数を定義せよ。 Haskellで可変長引数って一応できるらしいけど、なんか難しそう。 Text.Printfモジュールのソース読めっていう乱暴な(?)エントリ見つけたのでリンクしときます。 http://ja.doukaku.org/comm…

「Ansi Common Lisp」5章練習問題 - Haskell版

3. 引数の平方を返す関数を定義せよ。ただし、引数が5以下の正の整数である場合は平方の計算を行わないものとする。 mySquare :: Int -> Int mySquare x | (x >= 0 && x <= 5) = x | otherwise = x * x main = do print $ mySquare 0 print $ mySquare 5 pri…

「ANSI Common Lisp」5章読了

5章は制御構造のお話し。 普通(?)の言語なら、ここで条件分岐と繰り返しについて語られるところですが、いきなりブロックときたもんだ。 ブロック ブロックを作るには、progn、block、tagbodyがあるが、 普通はprogn、途中での飛び出し(処理中断)が必要であ…

「ANSI Common Lisp」4章練習問題 - Haskell版

1. 正方の配列(大きさが(n n)の配列)を引数としてそれを90度、時計回りに回転させる関数を定義せよ。 Lispの時に手抜きした分、めちゃくちゃ時間かかりました。。 -- 数列を右回りに90度回転 quarterTurn :: [[a]] -> [[a]] quarterTurn det = foldl makeDet…

「ANSI Common Lisp」4章読了

特別なデータ構造と題して、リスト以外のデータ構造を扱う。 本章ではLispのほかのデータ構造である、配列(ベクタとストリングを含む)、ストラクチャ、ハッシュ表の使用法を説明する。これらは、リストほど柔軟性はないかもしれないが、高速なアクセスとスペ…

「ANSI Common Lisp」3章練習問題 - Haskell版

2. もとのリストでの要素の並びを保持するように動作するunionの変形版を書け。 newUnion::(Eq a) => [a] -> [a] -> [a] newUnion x [] = x newUnion x (y:ys) = if elem y x then newUnion x ys else newUnion (x ++ [y]) ys main = print $ newUnion "abc"…

「ANSI Common Lisp」3章読了

リストに関する章。LispはLISt Processorの略なので、かなり重要と思われます。 コンス car(先頭要素へのポインタ)とcdr(残りの要素へのポインタ)の組をコンスというらしい。 Haskell的に書けば、xxs@(x:xs)記法(アズパターンという名前らしい)を使って、 ma…

「ANSI Common Lisp」2章練習問題 - Haskell版

Haskellに置き換えられそうなやつだけやってみる。 4.2つの数を引数として、大きい方を返す関数を定義せよ。 先日のエントリで、 大きい方って、同じ場合はどうするんでしょうね。 とりあえずnilを返すようにしてみました。 って書いたけど、Haskellにはnil…

「ANSI Common Lisp」2章読了

Lispを学ぶついでに、Haskellの復習もやってしまおうという企画(?)にしました。 が、どこまで出来るのかは不明です。。(と逃げを打っておく) リストから3番目の要素を取り出す thirdって関数があるらしい。便利。 (third '(1 2 3)) (third '(1 2)) (third '(…

m個からn個を取り出す順列生成でけた

とりあえずソース。 import List main = print $ perm_nm 2 [1,2,3,4] perm :: [Int] -> [[Int]] perm [] = [[]] perm xs = concat $ map perm2 xs where perm2 x = map (x:) $ perm $ delete x xs perm_nm :: Int -> [Int] -> [[Int]] perm_nm n [] = [[]] …

5つのビリヤード玉問題の重複解をなくす

前回のプログラムふつうのHaskellプログラミングのp99に、List.group関数の説明が載ってます。 group関数は、リストxsに連続して同じ要素が現れたらそれをリストにまとめて返します。 ですが、「同じ要素」の判定を自分で決められるgroupByを使います。 impo…

do式に書き換えてみる

ふつうのHaskellプログラミング p278上の文字列のリストを扱ったサンプルを、do式に書き換えてみる。 import Monad main = print $ monad ["aaa", "bbb", "ccc", "bbc"] monad xs = do x <- xs startsWithB x endsWithC x startsWithB :: String -> [String]…

0〜9の数字を使って、掛け算して、Go! リストモナド編

前回までのプログラムはこちらとりあえず、 数式を満たせるかアルゴリズム 掛け算の答えの先頭が0じゃないかアルゴリズム(って呼べるほどのものでもないが) をモナドでつなげてみることに。 つなげられるのがモナドのいいところ(なのか?) import List import…

リストモナドその2

リストモナドは、パズル解くのに有用そうなのでがんばってみる。以前Maybeモナドでやった、「文字列のリストからbで始まってcで終わる要素を取り出してみる。」ですが、リストモナドでやったらうまくいったので書いてみる。 main = print $ ["aaa", "bbb", "…

リストモナド

ふつうのHaskellプログラミング p270とりあえず本書より引用 リストモナドの典型的な用途として、経路探索が挙げられます。経路探索は将棋や囲碁をプログラムで解くときに必要です。例えば将棋では最初に銀を動かすか、それとも歩を動かすか、打てる手がたく…

Maybeモナド

ふつうのHaskellプログラミング p263書籍中ではlookup関数を使った例が示してあるので、別の例をやってみる。 リファレンスマニュアルを探したところ、 find :: (a -> Bool) -> [a] -> Maybe a ってのが、それっぽかったので、やってみる。 リスト[a]から、…

perm関数を理解する

前掲の perm [] = [[]] perm xs = concat [map (x:) $ perm (delete x xs) | x <- xs] を理解する。 まず、リスト内包表記(ふつうのHaskellプログラミング p147)で書かれているので、これを普通の書き方に直してみる。 map (x:) $ perm (delete x xs) の処理…

deriving宣言

ふつうのHaskellプログラミング p243昨日は、Anchor型にinstance宣言を使ってshow関数を定義することで、printに渡せるようにしましたが、もっと簡単にやる方法がありました。 それがderiving宣言です。 data Anchor = A String String deriving Show href :…

代数的データ型とdata宣言

ふつうのHaskellプログラミング p224 data Anchor = A String String みたいなことをやって、Stringのフィールドを二つ持つAnchor型を定義できるってことらしい。 Javaで言えば、 class Anchor { private String s1; private String s2; } みたいなところで…

5つのビリヤード玉問題も解けた

先日紹介した、 http://www.sampou.org/cgi-bin/haskell.cgi?Programming%3A%B6%CC%BC%EA%C8%A2%3A%C1%C8%B9%E7%A4%BB のサイトより、nPmの関数をパクってきて、作りました。 import List result = [1..21] main = print $ filter test $ perm [1..11] 5 div…

abc * de = fghijな0〜9

上の問題を一般化してみた。(固定な4をやめてみた) ついでに頭0禁止にしてみた。 import List main = putStr $ unlines $ map format $ filter test $ perm [0..9] perm :: [Int] -> [[Int]] perm [] = [[]] perm xs = concat [map (x:) $ perm (delete x xs…

関数型宣言の追記&nlistToStringの一般化 (0〜9の数字を使って、掛け算して、Go!解けた。)

前出の nlistToString nl = concatMap show nl ですが、数値のリストを文字列にするために用意した関数でしたが、別に数値のリストじゃなくてもよいのでは?と思い、以下のようにしてみることに。 listToString :: [a] -> String listToString l = concatMap…

無名関数

ふつうのHaskellプログラミング p196Javaの無名クラスとか、C#の匿名メソッドに概念は近そう。試しに、nlistToStringを無名関数で実装してみる。 main = print $ (\xs -> concatMap show xs) [1..10] 結果はこう。 "12345678910" さくっと動きました。 が、…

続々・0〜9の数字を使って、掛け算して、Go!解けた。

改行が余分に出るのはナゼだろう、、 は、unlinesでリストの各要素に改行が付けられて、さらにputStrLnで改行が付いたためだったらしい。 main = 直後のputStrLnをprintにしてみると分かる。 "402 x 39 = 15678\n483 x 12 = 05796\n495 x 36 = 17820\n" とい…

ガード

ふつうのHaskellプログラミング p174関数のパターンマッチの他に、条件も書けるということらしいです。例えば、階乗を求めるプログラム。 main = print $ fact 5 fact :: Int -> Int fact n = if n == 1 then 1 else n * fact (n-1) 結果は120(5 * 4 * 3 * 2…

続・0〜9の数字を使って、掛け算して、Go!解けた。

数値のリストを文字列に変換する方法が分かったので、早速試してみた。 import List main = putStrLn $ unlines $ map format $ filter test $ perm [0,1,2,3,5,6,7,8,9] perm [] = [[]] perm xs = concat [map (x:) $ perm (delete x xs) | x <- xs] test […

0〜9の数字を使って、掛け算して、Go!解けた。

順列生成アルゴリズムは、どこぞからパクってきたやつなので、まあインチキ(というか自分で理解してない)ですが、α版くらいの勢いでとりあえず出してみる。 問題はこちら:http://www5b.biglobe.ne.jp/~taka_2/jclass/0_9kake/index.html import List main =…

System.getProgNameを使ってみる

ふつうのHaskellプログラミング p87System.getArgsアクションの説明のところで、 なお、プログラム名を得たいときはSystem.getProgNameアクションを使います。 とあるので、早速サンプルを書いて動きを確かめてみる。 まず、ドキュメントを参照。 System.Env…