今回も順調だ(と、思う)。
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
をどこかで使ってみたかったので無理やり使ってみたが、今回はあまり効果的ではなかったかも。