बेशक, पहली बात यह है कि संख्या का मुख्य कारक है, जैसे ग्लोकोडर ने कहा।
n = p^a * q^b * r^c * ...
फिर
0 <= k <= a
के लिए m = n/p^a
- के गुणक विभाजन मिल जाए, जो प्रत्येक गुणक के लिए
k
- के additive विभाजन पाने के लिए बराबर है
p^k
के गुणक विभाजन मिल जाए, कहो m
का विभाजन, a-k
कारकों को वितरित करने के सभी विशिष्ट तरीके खोजेंकारकों
- के बीचके 2. और 3.
यह सुविधाजनक है डुप्लिकेट उत्पादन से बचने के लिए (भाजक, बहुलता) जोड़े की सूची (या सेट) के रूप में गुणक विभाजन के इलाज के लिए परिणामों को जोड़ सकते।
मैं हास्केल में कोड लिखा है, क्योंकि यह सबसे सुविधाजनक और भाषाओं मैं बात की इस तरह के लिए पता है की संक्षिप्त है:
module MultiPart (multiplicativePartitions) where
import Data.List (sort)
import Math.NumberTheory.Primes (factorise)
import Control.Arrow (first)
multiplicativePartitions :: Integer -> [[Integer]]
multiplicativePartitions n
| n < 1 = []
| n == 1 = [[]]
| otherwise = map ((>>= uncurry (flip replicate)) . sort) . pfPartitions $ factorise n
additivePartitions :: Int -> [[(Int,Int)]]
additivePartitions 0 = [[]]
additivePartitions n
| n < 0 = []
| otherwise = aParts n n
where
aParts :: Int -> Int -> [[(Int,Int)]]
aParts 0 _ = [[]]
aParts 1 m = [[(1,m)]]
aParts k m = withK ++ aParts (k-1) m
where
withK = do
let q = m `quot` k
j <- [q,q-1 .. 1]
[(k,j):prt | let r = m - j*k, prt <- aParts (min (k-1) r) r]
countedPartitions :: Int -> Int -> [[(Int,Int)]]
countedPartitions 0 count = [[(0,count)]]
countedPartitions quant count = cbParts quant quant count
where
prep _ 0 = id
prep m j = ((m,j):)
cbParts :: Int -> Int -> Int -> [[(Int,Int)]]
cbParts q 0 c
| q == 0 = if c == 0 then [[]] else [[(0,c)]]
| otherwise = error "Oops"
cbParts q 1 c
| c < q = [] -- should never happen
| c == q = [[(1,c)]]
| otherwise = [[(1,q),(0,c-q)]]
cbParts q m c = do
let lo = max 0 $ q - c*(m-1)
hi = q `quot` m
j <- [lo .. hi]
let r = q - j*m
m' = min (m-1) r
map (prep m j) $ cbParts r m' (c-j)
primePowerPartitions :: Integer -> Int -> [[(Integer,Int)]]
primePowerPartitions p e = map (map (first (p^))) $ additivePartitions e
distOne :: Integer -> Int -> Integer -> Int -> [[(Integer,Int)]]
distOne _ 0 d k = [[(d,k)]]
distOne p e d k = do
cap <- countedPartitions e k
return $ [(p^i*d,m) | (i,m) <- cap]
distribute :: Integer -> Int -> [(Integer,Int)] -> [[(Integer,Int)]]
distribute _ 0 xs = [xs]
distribute p e [(d,k)] = distOne p e d k
distribute p e ((d,k):dks) = do
j <- [0 .. e]
dps <- distOne p j d k
ys <- distribute p (e-j) dks
return $ dps ++ ys
distribute _ _ [] = []
pfPartitions :: [(Integer,Int)] -> [[(Integer,Int)]]
pfPartitions [] = [[]]
pfPartitions [(p,e)] = primePowerPartitions p e
pfPartitions ((p,e):pps) = do
cop <- pfPartitions pps
k <- [0 .. e]
ppp <- primePowerPartitions p k
mix <- distribute p (e-k) cop
return (ppp ++ mix)
यह विशेष रूप से अनुकूल नहीं है, लेकिन यह काम करता है।
कभी-कभी और परिणाम:
Prelude MultiPart> length $ multiplicativePartitions $ 10^10
59521
(0.03 secs, 53535264 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ 10^11
151958
(0.11 secs, 125850200 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ 10^12
379693
(0.26 secs, 296844616 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ product [2 .. 10]
70520
(0.07 secs, 72786128 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ product [2 .. 11]
425240
(0.36 secs, 460094808 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ product [2 .. 12]
2787810
(2.06 secs, 2572962320 bytes)
10^k
निश्चित रूप से विशेष रूप से आसान है क्योंकि केवल दो अभाज्य संख्या शामिल हैं (लेकिन squarefree संख्या अब भी आसान होता है) कर रहे हैं, factorials धीमी गति से पहले मिलता है। मुझे सूचियों की तुलना में बेहतर डेटा संरचनाओं के आदेश और पसंद के सावधान संगठन द्वारा लगता है, प्राप्त करने के लिए काफी कुछ है (शायद किसी को एक्सपोनेंट द्वारा प्रमुख कारकों को सॉर्ट करना चाहिए, लेकिन मुझे नहीं पता कि किसी को उच्चतम घाटियों के साथ शुरू करना चाहिए या नहीं सबसे कम)।
करीबी वोटों के साथ, आदर्श रूप से कुछ स्पष्टीकरण होना चाहिए कि आपको ऐसा क्यों लगता है कि इसे बंद करने की आवश्यकता है, ताकि ओपी अपनी गलतियों को सुधार सके (यदि कोई हो)। क्या अकेला करीबी मतदाता कृपया बात कर सकता है? – TCSGrad
बिना किसी स्पष्टीकरण के वोट बंद करें - हमेशा उनसे प्यार करता था! – TCSGrad
मैंने त्रुटि में एक करीबी वोट डाला। मैं क्षमाप्रार्थी हूं। –