Project Euler Problem 12
About - Project Euler を解いていたのですが、久しぶりに数学的に考えた問題があったのでメモ。
Problem11までは力技で解けていたのですが、以下の問題は愚直に計算したらまったく終わらかったです。
問題は、簡単に言うと「三角数 で、約数の数が500を超える最小のものを求めよ」となります。
三角数とは、リンク先のWikipediaにもありますが、一般項が以下のような数列のことです。
これより、一般項は等差数列の和になっているので、結局以下のような一般項として考えることができます。
さて、問題はこの の約数の個数を求める必要があります。 は自然数なので、 もしくは のどちらかは偶数です。よって、も自然数になります。
さらに、以下のことが成り立つ*1ので、の約数の個数は と、それぞれの約数の個数をかけ合わせたものになります。
ここまでくれば、あとはの小さい方から順番に約数の個数を求めていけば、無事に解答を求めることができました。
Haskellでのコードは以下に。
module Main where count_tri_divs n | even n = (count_divs $ n `div` 2) * (count_divs $ n + 1) | otherwise = (count_divs n) * (count_divs $ (n + 1) `div` 2) triangle n = (n * (n + 1)) `div` 2 count_divs n = length [1|x<-[1..n], n `mod` x == 0] main = print $ triangle $ head $ filter ((>500).count_tri_divs) [1..]