bitterharvest’s diary

A Bitter Harvestは小説の題名。作者は豪州のPeter Yeldham。苦闘の末に勝ちえた偏見からの解放は命との引換になったという悲しい物語

Haskell ドリル4 内包表記

1.概略

集合では10以下の整数全体の集合を { x | x <= 10 }と表すことができる。集合でのこのような記述を内包的記法という。内包的記法では、縦棒の左側で集合が満たすべき条件を記述する。

Haskellにおいても、内包表記において同様の記述を許している。例えば、1から100までの整数の中から偶数の集合は、内包表記を用いると、 [ x | x <- [1..100], mod x 2 == 0 ] である。 <-を集合の inと見なせば、内包表記は次のように読める。xは1から100までの整数の数列の要素で、2で割った余りが0である。ここでmod a bは整数aを整数bで割った余りである。

2.例題

問題:1から100までの整数の中から3でも5でも割れる数の集合mod15を求めなさい。
これは、偶数の集合を求めたときの内包表記を利用すればmod15 = [ x | x <- [1..100], mod x 3 == 0, mod x 5 == 0 ] となる。下図が実行例である。
f:id:bitterharvest:20141209152259p:plain

3.問題

それでは問題を解いてみよう。

問題1:1から100までの整数の中から2でも3でも5でも割れる数の集合mod1を求めなさい。

問題2:1から100までの整数の中から2でも3でも5でも割れない数の集合mod2を求めなさい。(ヒント:余りが0ではないかの検査はmod a b /= 0と書く。)

問題3:1から100までの整数の中から2か3で割れる数の集合mod3を求めなさい。(ヒント:Haskellでは論理和は||、論理積は&&である)

問題4:1から100までの整数の中から2で割れるが3で割れない数の集合mod4を求めなさい。

問題5:1から100までの整数の中から2で割れるかあるいは3で割れない数の集合mod5を求めなさい。

問題6:1から100までの整数の中から2で割れないかあるいは3で割れない数の集合mod6を求めなさい。

問題7: x,yが1から20までの整数であるとき、xとyの差が3になるxとyの対pair1を求めなさい。なお、対は (x,y) で表すことができる。従って [(x,y) | …] となる。

問題8:自然数x,yにおいて、xとyの和が11になるxとyの対pair2を求めなさい (ヒント:xもyも11以上にならないことを利用する)。

問題9: x,y,z が1から20までの整数であるとき、xとy+zの差が3になるxとyとzのタプルtupple1を求めなさい。なお、タプルは (x,y,z) で表すことができる。従って [(x,y,z) | …] となる。

問題10:自然数x,y,zにおいて、xとyとzの和が11になるxとyとzのタプルtupple2を求めなさい。

問題8の別解を下図に示しておく。
f:id:bitterharvest:20141209154305p:plain
上の解は、yの値を計算によって求めている。しかし、yの前にはletがついている。新たに変数を用いて、他のものに代わって、それを呼ぶとき(=を用いる)はその前にletをつける。ここでは、11-xに代わって、それをyで呼んでいるのでletをつける。