wvogel日記

自分用の技術備忘録が多めです.

最小値

さあ、今日もHaskell

2520は1から10の数字の全ての整数で割り切れる数字であり、そのような数字の中では最小の値である。
では、1から20までの全整数で割り切れる数字の中で最小の値はいくらか

という問題。

解いてみた。

main = print $ ans 2520 $ filter ans1 [11..20]

ans1 :: Int -> Bool
ans1 x = ans2 x 10

ans2 :: Int -> Int -> Bool
ans2 x 1 = True
ans2 x n
    | x `mod` n == 0 = False
    | otherwise = ans2 x (n-1)

ans :: Int -> [Int] -> Int
ans a [] = a*2
ans a (x:xs) = ans (a*x) xs

自分で計算した結果と合致。
大丈夫そうですね。
特に問題はない感じ。

ans1関数でまずリストをばらし、ans2に引き継ぐ。
ans2関数で、11〜20の値を、2〜10の値で順に割っていき、割りきれなかった値を保存していく。
ans関数で、取りだした値を2520にかけていく。
これで答えがわかります。


ただ、このコードには全く汎用性はありません。なぜなら、1〜50まで、みたいな問題の場合、32なんかは、2の5乗なので、上のコードでは弾かれますが、実際には、32÷8 = 4となり、2520に4を余計にかける処理が必要です。

今回は、11〜20の間では、素数と16だけが問題分の条件を満たすことがわかっていたのでこの方法を取りました。
なので、ans関数の中で、16÷8=2の2をかけています。

この方法はよろしくないのは、火を見るより明らか。当然です。
ただ、16のためだけに処理書くのが面倒だった笑