primeFactors 関数を少し修正。
前回は割れるだけ割ったあとに割れた回数だけ replicate してリストを作っていたが、
[(基数, 指数)]のタプルのリストを返すようにしてみた。
最初
Twitter でコメントをもらって
少し悩んだのが updateList のところで、これは[(基数, 指数)]のタプルのリストの中に基数nを加えるとき、
すでにリストの中にあれば指数をインクリメントし、リストの中になければ指数1の新しいタプルを追加する、
と処理をやりたかったので作成した。
list=[(2,1),(5,2)] の場合、n=1 であれば[(1,1),(2,1),(5,2)]を、n=2であれば[(2,2),(5,2)]を返す、という具合。
しかしこれはもっとスマートに書けそうな気がするなぁ…。
find や lookup を使うか、elem や elemIndex を使うか…
巧いやり方が思いつかなかったのでガードとか if とか使って泥臭く実装してみたが。
前回は割れるだけ割ったあとに割れた回数だけ replicate してリストを作っていたが、
[(基数, 指数)]のタプルのリストを返すようにしてみた。
primeFactors 50 -- 前回のバージョンでは [5,5,2] -- 今回のバージョンでは [(5,2),(2,1)]あとはwikipediaの約数の個数を参考に、 指数に1を足した値同士の積を取って約数の個数を求めるようにした。
最初
foldl (\n (_, a) -> n * (a + 1)) 1 $ primeFactors triNum
として求めていたが、Twitter でコメントをもらって
product . map ((+1).snd) $ primeFactors triNum
にしてみた。少し悩んだのが updateList のところで、これは[(基数, 指数)]のタプルのリストの中に基数nを加えるとき、
すでにリストの中にあれば指数をインクリメントし、リストの中になければ指数1の新しいタプルを追加する、
と処理をやりたかったので作成した。
list=[(2,1),(5,2)] の場合、n=1 であれば[(1,1),(2,1),(5,2)]を、n=2であれば[(2,2),(5,2)]を返す、という具合。
しかしこれはもっとスマートに書けそうな気がするなぁ…。
find や lookup を使うか、elem や elemIndex を使うか…
巧いやり方が思いつかなかったのでガードとか if とか使って泥臭く実装してみたが。