素数判定、素数の数え上げ、素数関数

  • Haskellのリストと集合内包表現(だけ)を使って素数判定、自然数の増加と疎の自然数までの素数の数の増加についての関数を作る
  • ある自然数素数であるかどうかの判定をその数より1より小さい自然数までのすべてで割った余りが0でないかどうかを判定するより、その自然数までの素数で割った余りが…とする方が処理は速そうだが、ひとまず、その工夫はしないでおこう
-- Haskell の集合の内包表現を使って
-- 次の手順で素数に関する処理をしてみる
-- myprime
-- まず2以上の自然数xを与え、[2..x-1]で割った余りが0になる個数を返す関数
let myprime x = (length ([y | y <- [2.. x-1], x `mod` y==0]) )
-- myprime2
-- myprime2の値が0であることが素数の判断条件なのでその真偽値を返す関数
let myprime2 x = ((myprime x) == 0)
-- myprime3
-- 2以上の自然数xを与え、[2 .. x]について、myprime2関数が真を返すことを条件に
-- 自然数x以下の素数を列挙する関数
let myprime3 x = [y | y <- [2 .. x], (myprime2 y)]
-- myprime4
-- 2以上の自然数x以下の素数の数を返す関数
myprime4 x = length ( myprime3 x)
-- myprime5
-- 2以上の自然数xを与え、[2 .. x]について、それぞれの自然数以下の素数の数を返す関数
-- この素数の数がどのように増えるかは、「リーマン予想」と関係する関数
let myprime5 x = [myprime4 y | y <- [2 ..x]]
-- 実行結果
Prelude> myprime 12
4
Prelude> myprime2 12
False
Prelude> myprime2 13
True
Prelude> myprime3 12
[2,3,5,7,11]
Prelude> myprime4 12
5
Prelude> myprime5 12
[1,2,2,3,3,4,4,4,4,5,5]

集合の内包表記、タプル

['\t' .. '^']
Prelude> ['\t' .. '^']
"\t\n\v\f\r\SO\SI\DLE\DC1\DC2\DC3\DC4\NAK\SYN\ETB\CAN\EM\SUB\ESC\FS\GS\RS\US !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^"
  • 方程式の近似解を求める
 [x | x <- [-10,-9.9999 .. 10], abs(x^2-6) < 0.001]
Prelude> [x | x <- [-10,-9.9999 .. 10], abs(x^2-6) < 0.001]
[-2.449600000017597,-2.449500000017597,-2.4494000000175973,-2.4493000000175975,2.449299999970986,2.4493999999709857,2.4494999999709854,2.449599999970985]
  • 格子点を作る
[(x,y) | x <- [1..5],y<-[1..5]]
Prelude> [(x,y) | x <- [1..5],y<-[1..5]]
[(1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,2),(2,3),(2,4),(2,5),(3,1),(3,2),(3,3),(3,4),(3,5),(4,1),(4,2),(4,3),(4,4),(4,5),(5,1),(5,2),(5,3),(5,4),(5,5)]