結果
問題 | No.106 素数が嫌い!2 |
ユーザー |
![]() |
提出日時 | 2020-07-31 11:25:25 |
言語 | Haskell (9.10.1) |
結果 |
AC
|
実行時間 | 63 ms / 5,000 ms |
コード長 | 4,456 bytes |
コンパイル時間 | 12,514 ms |
コンパイル使用メモリ | 207,904 KB |
実行使用メモリ | 24,288 KB |
最終ジャッジ日時 | 2024-07-06 01:30:10 |
合計ジャッジ時間 | 13,528 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 13 |
コンパイルメッセージ
Loaded package environment from /home/judge/.ghc/x86_64-linux-9.8.2/environments/default [1 of 2] Compiling Main ( Main.hs, Main.o ) Main.hs:125:34: warning: [GHC-63394] [-Wx-partial] In the use of ‘head’ (imported from Prelude, but defined in GHC.List): "This is a partial function, it throws an error on empty lists. Use pattern matching or Data.List.uncons instead. Consider refactoring to use Data.List.NonEmpty." | 125 | wheelSieve k = reverse ps ++ map head (pSieve p (cycle ns)) | ^^^^ [2 of 2] Linking a.out
ソースコード
importqualifiedControl.ArrowasArrowimportqualifiedControl.MonadasMonadimportqualifiedData.ByteString.CharasBSCimportqualifiedData.ListasListimportqualifiedData.Vector.UnboxedasVUimportqualifiedData.Vector.Unboxed.MutableasVUM-- solversolver::Int->Int->IOIntsolver n k = dotable <- VUM.replicate (n+1) 0 :: IO (VUM.IOVector Int)Monad.forM_ [2..n] $ \i -> dox <- VUM.read table iMonad.when (x == 0) $ doVUM.write table i 1Monad.forM_ [2 * i, 3 * i .. n] $ \j -> _modify table j (+1)Monad.foldM (_func k table) 0 [2 .. n]where_func k table c i = dox <- VUM.read table iif x >= kthen return (c + 1)else return c_modify::VUMIOVectorInt->Int->Int->Int->IO()_modify v i f = dox <- VUM.read v iVUM.write v i (f x)-- mainmain::IO()main = do(n, k) <- getABprint =<< solver n k-- iogetI::BSC8ByteString->MaybeIntBSC8ByteStringgetI = fmap (Arrow.second BSC8.tail) . BSC8.readIntgetAB::IOIntIntgetAB = (\vec -> (vec VU.! 0, vec VU.! 1)) . VU.unfoldrN 2 getI <$> BSC8.getLine-- primespSpin::Numint=>int->int->intpSpin x (y:ys) = x : pSpin (x + y) ystype PWheel int = ([int], [int])data PQueue int= Emtabley| Fork [int] [PQueue int]type Composites int = (PQueue int, [[int]])pEnqueue::Ordint=>int->PQueueint->PQueueintpEnqueue ns = pMerge (Fork ns [])pMergeAll::Ordint=>PQueueint->PQueueintpMergeAll [] = EmtableypMergeAll [x] = xpMergeAll (x:y:qs) = pMerge (pMerge x y) (pMergeAll qs)pDequeue::Ordint=>PQueueint->intPQueueintpDequeue (Fork ns qs) = (ns, pMergeAll qs)pMerge::Ordint=>PQueueint->PQueueint->PQueueintpMerge Emtabley y = ypMerge x Emtabley = xpMerge x y| prio x <= prio y = join x y| otherwise = join y xwhereprio (Fork (n:_) _) = njoin (Fork ns qs) q = Fork ns (q:qs)pDiscard::Ordint=>int->Compositesint->CompositesintpDiscard n ns| n == m = pDiscard n ms| otherwise = nswhere(m, ms) = pSplitComposites nspSplitComposites::Ordint=>Compositesint->intCompositesintpSplitComposites (Emtabley, xs:xss) = pSplitComposites (Fork xs [], xss)pSplitComposites (queue, xss@((x:xs):yss))| x < z = (x, pDiscard x (pEnqueue xs queue, yss))| otherwise = (z, pDiscard z (pEnqueue zs queue', xss))where(z:zs, queue') = pDequeue queuepSieveComps::OrdintNumint=>int->int->Compositesint->intpSieveComps cand ns@(m:ms) xs| cand == comp = pSieveComps (cand+m) ms ys| cand < comp = pSpin cand ns : pSieveComps (cand + m) ms xs| otherwise = pSieveComps cand ns yswhere(comp, ys) = pSplitComposites xspComposites::OrdintNumint=>int->int->CompositesintpComposites p ns = (Emtabley, map comps (pSpin p ns: pSieve p ns))wherecomps xs@(x:_) = map (x*) xspSieve::OrdintNumint=>int->int->intpSieve p ns@(m:ms) = pSpin p ns : pSieveComps (p+m) ms (pComposites p ns)pCancel::Integralint=>int->int->int->int->intpCancel 0 _ _ _ = []pCancel m p n (x:ys@(y:zs))| nx `mod` p > 0 = x : pCancel (m - x) p nx ys| otherwise = pCancel m p n (x+y:zs)wherenx = n + xpNext::Integralint=>PWheelint->PWheelintpNext (ps@(p:_), xs) = (py:ps, pCancel (product ps) p py ys)where(y:ys) = cycle xspy = p + ypWheel::Integralint=>Int->PWheelintpWheel n = iterate pNext ([2], [1]) !! n---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -------- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ------ ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----wheelSieve::Integralint=>Int->intwheelSieve k = reverse ps ++ map head (pSieve p (cycle ns))where(p:ps,ns) = pWheel kprimeFactors::Integralint=>int->intprimeFactors n = factors n (wheelSieve 6)wherefactors 1 _ = []factors m (p:ps)| m < p * p = [m]| r == 0 = p : factors q (p:ps)| otherwise = factors m pswhere(q, r) = quotRem m pprimes::Integralint=>intprimes = wheelSieve 6isPrime::Integralint=>int->BoolisPrime n| n > 1 = primeFactors n == [n]| otherwise = False