分解図

最近では、暇なときに、数を素因数または「 因数分解図」に分解して得られる図を生成するプログラムを書きました。



700は次のようになります。





ポイントの場所によって、合計で7 * 5 * 5 * 2 * 2があることが簡単にわかります。



以下は、これがどのように機能するかの説明です。



開始するには、いくつかのインポートがあります。整数を素因数に分解する関数と、ダイアグラムを描画するためのライブラリです。



module Factorization where import Math.NumberTheory.Primes.Factorisation (factorise) import Diagrams.Prelude import Diagrams.Backend.Cairo.CmdLine type Picture = Diagram Cairo R2
      
      







primeLayout関数は、整数n(素数である必要があります)と何らかのイメージを取り、イメージのn個のコピーを対称的に配置します。



 primeLayout :: Integer -> Picture -> Picture
      
      







2の場合、特別な場合があります。画像が高さよりも広い場合、2つのコピーが上下に描画されます。それ以外の場合は、横に並べて描画されます。 どちらの場合も、コピー間に小さなスペースを追加します(それぞれ高さまたは幅の半分に等しい)。



 primeLayout 2 d | width d > height d = d === strutY (height d / 2) === d | otherwise = d ||| strutX (width d / 2) ||| d
      
      







つまり、2に等しい係数がいくつかあり、primeLayoutを数回呼び出すと、次のような結果になります。





常に隣同士にコピーを描くと、



それはそれほど美しく明確ではありません。



その他の数値については、適切なサイズの正多角形を作成し、多角形の頂点に沿ってコピーを配置します。



 primeLayout pd = decoratePath pts (repeat d) where pts = polygon with { polyType = PolyRegular (fromIntegral p) r , polyOrient = OrientH } w = max (width d) (height d) r = w * c / sin (tau / (2 * fromIntegral p)) c = 0.75
      
      







たとえば、緑の正方形に適用されたprimeLayout 5は次のとおりです。





さらに、素因数のリストを使用して、画像全体を再帰的に作成します。

リストが空の場合、これは数値1に対応するため、黒い点を描画するだけです。



 factorDiagram' :: [Integer] -> Diagram Cairo R2 factorDiagram' [] = circle 1 # fc black
      
      









それ以外の場合、最初の素数がpで残りがpsの場合、残りの素数psからイメージを再帰的に作成し、primeLayout関数を使用してこのイメージのp個のコピーを描画します。



 factorDiagram' (p:ps) = primeLayout p (factorDiagram' ps) # centerXY
      
      







最後に、数値を因数分解チャートに変換するために、それを素因数に分解し、素数のリストに正規化し、大きな数値が先頭にくるように反転し、factorDiagram 'を呼び出します。



 factorDiagram :: Integer -> Diagram Cairo R2 factorDiagram = factorDiagram' . reverse . concatMap (uncurry $ flip replicate) . factorise
      
      







そして出来上がり! もちろん、これは{2、3、5、7}(そして多分11)の範囲の数値でのみうまく機能します。 たとえば、121は次のようになります。





611:





以下は、1〜36のすべての整数のグラフです。





トリプルの図は、 シェルピンスキーの三角形であるため、特に興味深いものです。 ここで、たとえば、3 5 = 243:





2度も非常に良好で、 カントールダストと呼ばれるフラクタルです。 これは2 10 = 1024です:





そして最後に104:





投稿者:Brent Yorgey。 オリジナル



PS:あまり実用的ではありませんが(数を素因数に分解することを示す場合を除いて)、面白いように見えます。 :)

元の記事の最後に、著者は、誰でも番号を入力して結果を確認できるように、アプリケーションをWebサイトの形式で配置したいと述べています。

私はjavascriptで似たようなことをしました 。希望する人はここで実験できます 。 haskellバージョンよりもパフォーマンスが低いため、大きな数字を使用した方が正確です。

PPS:サンドボックスから投稿するので、適切な方法で翻訳を設計しなかったことを事前に謝罪します。



UPD: lanyは、同様のチャートビジュアライザーの作成に関する非常に興味深い記事を書きましたが、多数のパフォーマンスが向上しています。 3628800の分解がどのように見えるかを知りたいですか? ここにあなたに。 :)



All Articles