Problem 108
コンテンツ
http://projecteuler.net/index.php?section=problems&id=108
1/a+1/b=1/n
ですが、b=n+b’と書き換えると
n^2がb’で割り切れることが分かる。
従って、n^2が1999個の約数を持つ最小のnを探せばよい。
import Number import Data.List import Data.Maybe descending xs = and . zipWith (>=) xs $ tail xs succ' (n+1) xs = let (ys,z:zs) = splitAt n xs in ys++[z+1]++zs next n (Just xs) | descending ys = Just ys | otherwise = Nothing where ys = succ' n xs p108 = Just (replicate 7 ) : foldr1 mergeMaybe [map (next n) p108|n<-[1..7]] where mergeMaybe (Just u:us) (Just v:vs ) | decode u == decode v = Just u : mergeMaybe us vs | decode u < decode v = Just u : mergeMaybe us (Just v:vs) | decode u > decode v = Just v : mergeMaybe (Just u:us) vs mergeMaybe (Just u:us) (Nothing:vs) = Just u: mergeMaybe us vs mergeMaybe (Nothing:us) (Just v:vs) = Just v: mergeMaybe us vs mergeMaybe (Nothing:us) (Nothing:vs) = Nothing:mergeMaybe us vs decode = product.zipWith (^) prime where prime = take 7 primes main = print.decode.fromJust.find over.catMaybes$p108 where over xs = 1999 < (product.map (x->2*x+1) )xs
イメージとしてはハミング数と同じ。
最小を探すので、降順の条件を入れると、探索範囲がぐっとせまくなる、ような気がする。
mergeMaybeの実装に手間取った。
素数7で十分な理由は
7>log 1999 / log 3
から
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)