今回も順調だ(と、思う)。
iterateをいい感じに使えた(と、思う)。
Problem 55. Lychrel numbers(Lychrel数)
反転した値をiterateで加算し続けて回文数を探す。
scanlで加算し続けるリストを作っても良さそうだったけど、こちらのほうが簡潔かな、と思う。
元の数自身が回文数だとisLychrelが真となってしまい、「回文数かつLychrel数であるもの」を正確に判定できないため、
iterate addReverseNumした値をtailしてからfindするようにしてみたが、
ちょっと回りくどい気がする…。
もう少し綺麗に書けないかなぁ。
Problem 56. Powerful digit sum(もっとべき乗の数字和)
Problem 16を流用してすんなり書けた。
Problem 57. Square root convergents(平方根の近似分数)
前2問に比べると少し悩んだ。
Data.Ratioを使えばよさそうだな、とは思いついたが、連分数をどうHaskellコードで表現したものか。
1で割るところを分子と分母を入れ替えるreciprocal関数で行い、
iterate (\n -> reciprocal (2 + n)) (1 % 2)で連分数を表し、
1を足すところは個別に行う、という処理にしてみた。
とりあえずこれで解答は出せたけど後々読み返して何をやっているか読み解くのが辛そうなコードになったかな…。
また、こちらを元に書き換えてみた。
(/) :: Fractional a => a -> a -> aなのでnがRatioだったら1/nもRatioだった。
さらに標準にrecip関数があるのでわざわざreciprocal関数を自作する必要もなかった。
euler57-2.hsはそもそもrecipでの分子分母の入れ替えを必要としない書き方。
こちらのsqrt2を見てみるとなるほど、という感じだが、これも自分では思いつかなかっただろうな…。
あとは最近覚えたData.Function.onをどこかで使ってみたかったので無理やり使ってみたが、
今回はあまり効果的ではなかったかも。

Copyright© 2011-2021 Shunsuke Otani All Right Reserved .