दिए गए आकार के एबेलियन समूहों की गिनती


14

पृष्ठभूमि

पिछली बार, हमने दिए गए आकार के समूहों को गिना था , जो एक गैर-तुच्छ समस्या है।

इस बार, हम केवल Abelian समूहों की गिनती करेंगे , यानी, एक कम्यूटेटिव ऑपरेशन वाले समूह। औपचारिक रूप से, एक समूह (G, ∗) एबेलियन है यदि x y y = y for x सभी x, y के लिए G में है

समस्या इस तरह से बहुत सरल हो जाती है, इसलिए हम उन्हें कुशलता से गिनने जा रहे हैं।

कार्य

एक प्रोग्राम या फ़ंक्शन लिखें जो एक गैर-नकारात्मक पूर्णांक n को इनपुट और प्रिंट के रूप में स्वीकार करता है या आदेश n के गैर-आइसोमॉर्फिक एबेलियन समूहों की संख्या लौटाता है ।

समूहों की संख्या की गणना करने का एक तरीका - जिसे हम ए (एन) द्वारा निरूपित करेंगे - निम्नलिखित का अवलोकन करके है:

  • अ (०) = ०

  • अगर पी एक प्रमुख है, एक (पी कश्मीर ) के पूर्णांक विभाजन की संख्या के बराबर है कश्मीर । (cfr। OEIS A000041 )

  • यदि n = mk , और m और k सह-प्रधान हैं, A (n) = A (m) A (k)

आप इस (या ) की गणना के किसी अन्य तरीके का उपयोग कर सकते हैं ।

परीक्षण के मामलों

Input               Output
0                   0
1                   1
2                   1
3                   1
4                   2
5                   1
6                   1
7                   1
8                   3
9                   2
10                  1
11                  1
12                  2
13                  1
14                  1
15                  1
16                  5
17                  1
18                  2
19                  1
20                  2
4611686018427387904 1300156
5587736968198167552 155232
9223371994482243049 2

( OEIS A000688 से लिया गया )

अतिरिक्त नियम

  • पर्याप्त समय, रैम और एक रजिस्टर आकार जो इनपुट को पकड़ सकता है, को देखते हुए, आपका कोड मनमाने ढंग से बड़े पूर्णांक के लिए काम करना चाहिए (सिद्धांत में)।

  • आपका कोड 0 और 2 63 - 1 के बीच सभी पूर्णांकों के लिए काम करना चाहिए और मेरी मशीन (Intel i7-3770, 16 GiB RAM, Fedora 21) पर 10 मिनट के भीतर खत्म करना होगा।

    कृपया अपना उत्तर सबमिट करने से पहले अंतिम तीन परीक्षण मामलों के लिए अपना कोड सुनिश्चित कर लें।

  • अंतर्निहित कार्य जो इस कार्य को तुच्छ बनाते हैं, जैसे कि मैथेमेटिका FiniteAbelianGroupCount, की अनुमति नहीं है।

  • बिल्ट-इन जो किसी संख्या के पूर्णांक विभाजन को लौटाता है या गिनता है या किसी सूची के विभाजन की अनुमति नहीं है।

  • मानक नियम लागू होते हैं।


इस चुनौती के लिए पायथ की मुख्य कारक प्रणाली बहुत धीमी है - मुझे इसे ठीक करने की आवश्यकता है।
isaacg

जवाबों:


3

CJam ( 39 38 बाइट्स)

qimF{~M\{_ee{~\)<1b}%1+a\+}*0=1be&}%:*

ऑनलाइन डेमो

यह एक मुख्य कारक खोजने की सुझाई गई रेखा ( mF) का अनुसरण करता है और फिर प्रत्येक शक्ति के विभाजन की गणना करता है और उनके उत्पाद लेता है।

इसके लिए दो विशेष मामले हैं mF: यह कारक के 0रूप में 0^1और के 1रूप में 1^1। उत्तरार्द्ध को विशेष उपचार की आवश्यकता नहीं है: आकार 1 का एक एबेलियन समूह है, और 1 का एक विभाजन है। हालांकि, शून्य को एक विशेष मामले की आवश्यकता होती है।

विभाजन की गिनती के लिए एक पुनरावृत्ति का उपयोग करता है A008284(n, k), भागों nमें विभाजन की संख्या k। OEIS में इसे दिया गया है

T(n, k) = Sum_{i=1..k} T(n-k, i), for 1<=k<=n-1; T(n, n) = 1 for n >= 1.

लेकिन मुझे लगता है कि यह राशि से लेकर के रूप में सोचने के लिए अधिक उपयोगी 1है min(k, n-k)

विच्छेदन

q~              e# Parse input into an integer
mF              e# Factorise it
{               e# For each factor p^a
  ~             e#   Split the array [p a]
                e#   The following lines count partitions of a
                e#   (Note: they would be buggy if a were ever 0, but it isn't)
  M\{           e#   Starting with a table of zero rows, repeat a times
    _ee         e#     Copy table and pair each row with its index
    {~\)<1b}%   e#     Extract that prepended index and use it to sum for each j
                e#     the first jth items of row j
    1+          e#     Append a 1 for P(i, i)
    a\+         e#     Prepend the new row to the table (which is stored in reverse)
  }*
  0=1b          e#   Sum the elements in the latest (first) row

  e&            e#   If p was 0 then replace with 0
}%
:*              e# Take the product

5

CJam, 50 49 47 43 बाइट्स

ri_mF{1=_L{1$0>{,f{):X-Xj}:+}{;!}?}2j}%:*e&

CJam के बिलियन फैक्टराइजेशन mFऔर इस पायथन विभाजन संख्या फ़ंक्शन के एक यादगार पोर्ट का उपयोग करता है :

p=lambda n,x:n==0 or n>0and sum(p(n+~a,a+1)for a in range(x))

या अपुष्ट:

def p(n, x): # Call like p(n, n). n is number remaining, x is max part size
  if n > 0:
    return sum(p(n-a-1,a+1)for a in range(x))
  else:
    return (n==0)

@ RetoKoradi के जवाब की तरह, अंतिम मामले में ऑफलाइन दुभाषिया पर लगभग 17 सेकंड लगते हैं क्योंकि संख्या को फैक्टर करने में CJam को कितना समय लगता है। इसलिए मैंने इसे इस ऑनलाइन टेस्ट सूट से बाहर कर दिया ।

पूरी व्याख्या

[Main body]
ri                                Read input and convert to int
  _          e&                   Logical AND input with final result to special case 0 
   mF                             Factorise input into [base, exponent] pairs
     {...}%                       Map, converting each pair to a partition number
           :*                     Take product

[Pair -> partition]
1=_                               Get exponent and copy (n,x in above Python)
   L                              Initialise empty cache
    {                       }2j   Memoise with 2 arguments
     1$0>                         Check if n > 0
         {            }{  }?      Execute first block if yes, else second block
                        ;!        Return (n == 0)
          ,f{      }              For each a in range(x) ...
             ):X-Xj               Call p(n-a-1,a+1) recursively
                    :+            Sum the results

4

गणितज्ञ, 96 94 88 बाइट्स

f=1##&@@#&;f[SeriesCoefficient[1/f[1-x^Range@#],{x,0,#}]&/@Last/@FactorInteger@#]Sign@#&

मैं उस गणितज्ञ के साथ कुशल नहीं हूं, लेकिन मुझे लगा कि मैं इसे आजमाऊंगा। @ मार्टिन-बर्नर -6 बाइट्स के लिए धन्यवाद।

यह पूर्णांक विभाजन के लिए जनरेटिंग फ़ंक्शन सूत्र का उपयोग करता है।


3

सीजेएम, 58 बाइट्स

li_mF{1=_L{_1>{_2$<{\;_j}{\,f{)_@\-j}:+}?}{;;1}?}2j}%:*\g*

इसे ऑनलाइन आज़माएं

ऑनलाइन इंटरप्रेटर में बहुत अंतिम परीक्षण उदाहरण हमेशा के लिए (या कम से कम लंबे समय तक मैं प्रतीक्षा करने के लिए तैयार था) लेता है, लेकिन मेरे लैपटॉप पर सीजेएम के ऑफ़लाइन संस्करण के साथ 17 सेकंड में समाप्त होता है। अन्य सभी परीक्षण उदाहरण बहुत तात्कालिक हैं।

यह सीजेएम mFऑपरेटर का उपयोग करता है , जो एक्सपेक्टर्स के साथ प्रमुख कारक देता है। परिणाम तब प्रत्येक घातांक के लिए विभाजन का उत्पाद मायने रखता है।

कोड का मुख्य भाग विभाजन की गणना करता है। मैंने विकिपीडिया पृष्ठ पर पुनरावर्ती एल्गोरिदम को लागू किया , jसंस्मरण के साथ पुनरावृत्ति का समर्थन करने वाले ऑपरेटर का उपयोग करके ।

स्पष्टीकरण:

li    Get input and convert to int.
_     Make a copy to handle 0 special case at the end.
mF    Factorization with exponents.
{     Loop over factors.
  1=    Take exponent from [factor exponent] pair.
  _     Repeat it, recursive calls are initiated with p(n, n).
  L     Empty list as start point of memoization state.
  {     Start recursive block. Argument order is (m, n), opposite of Wikipedia.
    _1>   Check for n > 1.
    {     Start n > 1 case.
      _2$   Copy both m and n.
      <     Check for n < m.
      {     n < m case.
        \;    Pop m.
        _     Copy n.
        j     Make the p(n, n) recursive call.
      }     End n < m case.
      {     Main part of algorithm that makes recursive calls in loop.
        \,    Generate [0 1 ... m-1] range for k.
        f{    Start loop over k.
          )     Increment, since k goes from 1 to m.
          _     Copy k.
          @\    Rotate n to top, and swap. Now have k n k at top of stack.
          -     Subtract, now have k n-k at top of stack.
          j     Make the p(n-k, k) recursive call.
        }     End loop over k.
        :+    Sum up all the values.
      }?    Ternaray operator for n < m condition.
    }     End n > 1 case.
    {     n <= 1 case.
      ;;1   Pop m, n values, and produce 1 as result.
    }?    Ternary operator for n > 1 condition.
  }2j   Recursive call with memoization, using 2 values.
}%    End loop over factors.
:*    Multiply all values.
\     Swap original input to top.
g     Signum.
*     Multiply to get 0 output for 0 input.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.