Problem 183

http://projecteuler.net/index.php?section=problems&id=183

logとって微分した。

del :: Integral a => a -> a -> a
del p = until ((0/=).(`mod` p)) (`div` p)

d ::Integral a => a -> a
d n | (1==).del 5.del 2.div r' $ (gcd n r') = -n
    | otherwise                             = n
    where r = fromIntegral.floor $ fromIntegral n / (exp 1)
          r' | (r+1)*log(r+1) >= log' n + r*log r = floor r
             | otherwise                          = floor r + 1
          log' = log.fromIntegral

p183 n = sum.map d $ [5..n]

実は最大値は近いほうで達成されるらしい。
つまり、下でよい。

del :: Integral a => a -> a -> a
del p = until ((0/=).(`mod` p)) (`div` p)

d :: Integral a => a -> a
d n | (1==).del 5.del 2.div r $ (gcd n r) = -n
    | otherwise                           = n
    where r = round$ fromIntegral n / (exp 1)

p183 n = sum.map d $ [5..n]