1.自然数を数学的な模様にする
中学生のとき、素因数分解を学んだ。与えられた自然数を、割り切れない数(素数)の積で表したものだ。例えば、102は素数17,3,2の積で表すことができる。
自然数をその構成要素である素数を用いて絵画的に表すことを考えたのは、Diagramsの開発者でもあるBrent Yorgeyである。彼のアイデアは次のようになっている。まず、構成要素となっている素数を大きい順にならべる。102の場合には{17,3,2}である。そして、一番大きな素数と同じだけの頂点を有する正多角形を描く。102の場合であれば正17角形である。次に、各頂点の周りにその次に大きな素数と同じ頂点を有する正多角形を描く。102の場合であれば、正3角形である。この操作を続ける。最後の整数に出くわしたら、同じように、正多角形を書いた後、その各頂点に小円を描く。これにより、自然数と同じだけの小円が描かれるが、素因数分解という構造的な表現を用いて表したものとなる。
自然数をこのように絵画的に表した場合の、アニメーションがあるので、こちらを見るとよい。
2.プログラムを書いてみる
Yorgey自身のプログラムもあるし、また、モジュールDiagrams.TwoD.Factorizationをインストールすれば簡単に利用することもできるが、それほど難しいプログラムでもないので、基本的な部分を作成してみる。完成したプログラムは以下のようである。
import Diagrams.Prelude import Diagrams.Backend.Rasterific.CmdLine import Math.NumberTheory.Primes.Factorisation (factorise) node = circle 0.2 # fc green factor :: [Int] -> Diagram B R2 factor [] = error "We need a number." factor [x] = decorateTrail (regPoly x 1) (replicate x node) # centerXY factor (x:xs) = decorateTrail (regPoly x (fromIntegral (3 ^ (length xs)))) (map (\n -> (factor xs # rotateBy ((fromIntegral n) / (fromIntegral x))) # centerXY) [1..x]) factorList :: [Int] factorList = factorise 1365 # concatMap (uncurry $ flip replicate) # reverse # map fromIntegral example = factorList # factor # centerXY # lw none # fc white # pad 1.1 --example = [13,7,5,3] # factor # centerXY # lw none # fc white # pad 1.1 main = mainWith example
プログラムを実行したときの例をいくつか挙げておく。
34の場合は次のとおりである。
105の場合は次のとおりである。
1365の場合は次のとおりである。