リスト内包表記

リストを作るとき,要素を列挙したり範囲を指定するほかに,計算をしながら作ることもできる。
たとえば100以下の偶数のリストは

*Main> [x | x <- [1..100], x mod 2 == 0]
[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56
,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100]

| の左側がリストの要素,右側がその条件になる。条件には次のことが書ける。

  • パターン <- リスト
  • 真偽式
  • let パターン = 式

上の例では,パターン <- リスト と真偽式と使っている。3番目の let ~は「入門Haskell」には詳しい説明がないけど,「あまり使わない」とか書いてあるからそういうことにしとこう。

以下,練習。
三角数

triangular a = [n*(n+1)/2 | n <- [1..a]]
*Main> triangular 50
[1.0,3.0,6.0,10.0,15.0,21.0,28.0,36.0,45.0,55.0,66.0,78.0,91.0,105.0,120.0,136.0
,153.0,171.0,190.0,210.0,231.0,253.0,276.0,300.0,325.0,351.0,378.0,406.0,435.0,4
65.0,496.0,528.0,561.0,595.0,630.0,666.0,703.0,741.0,780.0,820.0,861.0,903.0,946
.0,990.0,1035.0,1081.0,1128.0,1176.0,1225.0,1275.0]

平方数

square a = [n*n | n <- [1..a]]
*Main> square 50
[1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484,529
,576,625,676,729,784,841,900,961,1024,1089,1156,1225,1296,1369,1444,1521,1600,16
81,1764,1849,1936,2025,2116,2209,2304,2401,2500]

ピタゴラス数

pythagorean a = [(x, y, z) | x <- [1..a], y <- [1..a], z <- [1..a], x < y, x*x + y*y == z*z]
*Main> pythagorean 50
[(3,4,5),(5,12,13),(6,8,10),(7,24,25),(8,15,17),(9,12,15),(9,40,41),(10,24,26),(
12,16,20),(12,35,37),(14,48,50),(15,20,25),(15,36,39),(16,30,34),(18,24,30),(20,
21,29),(21,28,35),(24,32,40),(27,36,45),(30,40,50)]

ピタゴラス数って結構あるんだな。

カテゴリー: Haskell パーマリンク

3 Responses to リスト内包表記

  1. IO () のコメント:

    単に「整数/整数」すると浮動小数点数の結果になるのでもし「整数 割る 整数」が整数になる演算子を知っていればそれを三角数に使ってみては。

  2. takatoh のコメント:

    ふむ。こうですね。
    triangular a = [n*(n+1) div 2 | n <- [1..a]]

  3. IO () のコメント:

    ピタゴラス数の中の(6,8,10)や(9,12,15)のようにx,y,zに公約数を持つものは外すともっといい感じになるかも。

IO () へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください