0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事は ひとりアドベントカレンダーRosettaCodeで楽しむプログラミング Advent Calendar 2025の16日めの記事です。

タスク

指定された個数 n の異なる素数で、その和が指定された整数 x になるものを見つける。
複数の方法があるときは、極力小さい素数を使うものを示すこと。

考える

0~n個の素数の和で合計が y になる組み合わせ、というDPでもするのかと思ったけれど、そんなに難しく考えなくとも、単純に深さ優先探索で降りていけばできそうだ。

import Text.Printf
import Data.List

import Data.Numbers.Primes
import Control.Monad

search :: Int -> Int -> [Int] -> Maybe [Int]
search x 1 (p:_ ) = if p <= x && isPrime x then Just [x] else Nothing
search x k (p:ps)
  | x <= p    = Nothing
  | otherwise = fmap (p :) (search (x - p) (pred k) ps) `mplus` search x k ps

main :: IO ()
main = forM_ test $ \(x,k) ->
      case search x k primes of
        Nothing -> printf "Partitioning %5d with %2d primes: is not possible\n" x k
        Just ps -> printf "Partitioned  %5d with %2d primes: %s\n" x k (intercalate "+" $ map show ps)
  where
    test = [(99809, 1), (18, 2), (19, 3), (20, 4), (2017, 24)] ++
           [(22699, i) | i <- [1 .. 4]] ++ [(40355, 3)]
ghci> main
Partitioned 99809 with  1 primes: 99809
Partitioned    18 with  2 primes: 5+13
Partitioned    19 with  3 primes: 3+5+11
Partitioned    20 with  4 primes: (not possible)
Partitioned  2017 with 24 primes: 2+3+5+7+11+13+17+19+23+29+31+37+41+43+47+53+59+61+67+71+73+79+97+1129
Partitioned 22699 with  1 primes: 22699
Partitioned 22699 with  2 primes: 2+22697
Partitioned 22699 with  3 primes: 3+5+22691
Partitioned 22699 with  4 primes: 2+3+43+22651
Partitioned 40355 with  3 primes: 3+139+40213
(0.06 secs, 25,783,088 bytes)

最後の一つになったら、それが素数で、まだ使ってよいものならOK、さもなくば失敗。
複数個の素数を使うとき、素数リストの先頭 p を引いてまだ数が残る必要がある。
p を使って残りを再帰でするか、使わずに再帰するかの2通りに分岐する。

出力のお化粧含めても、ページ中のどれよりもすっきりとまとまったコードになっていると思う。
Haskell版のも含めて。
ていうかJはもっと簡潔に書けるでしょ絶対。知らんけど。

今日は小ネタでした。

0
0
0

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?