Magicode logo
Magicode
2 min read

【倍数】一緒に考えませんか? #Project Euler

https://cdn.apollon.ai/media/notebox/0d6d00b7-ca71-40f8-b9bb-7f91c3bce223.jpeg

問1

1000未満の3または5の倍数の和を求める
Project Euler ※解法の公開は問1~100のみ可

考え方

1000未満の3または5の倍数の和を計算する

まずは中間構造を考える
必要な値をリストでもってsumをとることにする
solve :: Int
solve = sum [1000未満の3の倍数または5の倍数の整数]

-- 内包表記でうまく出来そう
solve = sum [ n | n <- [1..999], n `mod` 3 == 0 || n `mod` 5 == 0]
haskell
solve :: Int
solve = sum [ n | n <- [1..999], n `mod` 3 == 0 || n `mod` 5 == 0]
print solve

233168

考え方2

リストを用いず単純な計算をする

和を個別に計算して合計を求める
solve2 :: Int
solve2 = 3の倍数の和 + 5の倍数の和 - 15の倍数の和

和の公式 Σ (1 → k) nk

sigma :: Int -> Int -> Int
sigma n k = n * k*(1 + k) / 2

-- 1000未満の場合の一般化
sigma_1000 :: Int -> Int
sigma_1000 n = sigma n (999 `div` n)

最後に答えを書き直す

solve2 = sigma_1000 3 + sigma_1000 5 - sigma_1000 15
haskell
solve2 :: Int
solve2 = sigma_1000 3 + sigma_1000 5 - sigma_1000 15
sigma :: Int -> Int -> Int
sigma n k = n * k*(1 + k) `div` 2
sigma_1000 :: Int -> Int
sigma_1000 n = sigma n (999 `div` n)
print solve2

233168

末筆ながら

ご意見求む!!

回答1の方が直感的に分かりやすい気がするけど、回答2の方が(完全に)優れてる?
回答1のリスト内包表記で条件部分(modらへん)でもっとおしゃれな書き方がありそう

Haskellerさんへ

計算量, 見やすさ, 文化的な観点から見て改善点や他回答があればぜひお願いします!

スキル指標

実務1年程度のへっぽこプログラマーなので暖かくも厳しく見守ってください
読んだ本
  • すごいH本
  • 関数プログラミング実践入門 (途中)
つまり構文を知った程度で、関数型言語っぽい書き方を学び中です

Discussion

コメントにはログインが必要です。