LoginSignup
0
0

More than 5 years have passed since last update.

Project Euler No. 5

Last updated at Posted at 2013-12-05

Problem

$2520$ is the smallest number that can be divided by each of the numbers from $1$ to $10$ without any remainder.

What is the smallest positive number that is evenly divisible by all of the numbers from $1$ to $20$?

Code in Haskell

Euler_005.hs
module Main where

-- ユークリッドの互除法そのまま (追記 ← 大嘘)
greatestCD a 0 = a
greatestCD a b
  | a>=b = greatestCD b (a - b)
  | a<b  = greatestCD b (b - a)

{- 
 コメント欄で教えていただきました。
 こっちが本来の「ユークリッドの互除法」で
これなら計算も一瞬で終わります……実に(私の頭が)ひどい。

greatestCD m 0 = m
greatestCD m n = greatestCD n (mod m n)

-}


-- LCMは積をGCDで除したもの
leastCM a b = a*b `div` (greatCD a b)
leastCMofALL as = foldl leastCM 1 as

main = print answer
  where answer = leastCMofALL [1..20]

これは予想通り恐ろしく遅い。$1$から$20$ならなんとかなるが、$1$から$30$までにしてみると、もうまったく終わらない。

追記 上のコード内のコメントにある通りで、「ユークリッドの互除法」は悪くない。残念なのは私でした。きちんとしたヴァージョンだと爆速で終わるので、下記のものはまったく余計な代物です。でも恥の証として残しておく。

そこで、$1$から$n$までを素因数分解して、各素因数ごとに指数の最大値を取って合成するという方策を取ってみた(その方策を実行する仕方がダサいのは私が情弱だからである)。素因数分解はProblem No. 3のものを転用する:

Euler_005bis.hs
module Main where
import Control.Applicative
import Data.List
import Data.Ord (comparing)
import System.Environment (getArgs)

factoring n fs (x:xs)
  | n == 1 = fs
  | (mod n x == 0) = factoring (div n x) (x:fs) (x:xs)
  |otherwise = factoring n fs xs

factors n = group $ factoring n [] [2..n]
factorset n =  sortBy (comparing length) $ concat $ map factors [2..n]

reduce [] = []
reduce (x:xs)
  | or $ map (isPrefixOf x) xs = reduce xs
  |otherwise = x: reduce xs

build [] = 1
build (x:xs) = ((head x)^(length x)) * build xs

solve = build . reduce . factorset

-- コマンドライン引数で正整数を取って結果を返す
main =  solve<$>read<$>(!!0)<$>getArgs >>= print

明らかにムダがあるはずなのだが、それでもこれは見事に早かった。

Answer

2*******0

Comments

ちなみに$1$から$30$までだと$2329089562800$である。

MEMO

mainがコマンドライン引数を取るときにはghciではmainではなく:mainを使うこと(情弱なので初めて知った)。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0