एक क्रमचय के चक्रों की संख्या


23

पूर्णांक के क्रमांक पर विचार करें 1, ... n, जैसे कि इसके लिए यह एक n = 6:

[5,2,4,3,6,1]

आप से एक मानचित्रण के रूप में परिवर्तन देखते हैं, तो [1,2,3,4,5,6]करने के लिए [5,2,4,3,6,1], परिवर्तन संबंध तोड़ना में decomponsed किया जा सकता है चक्र । एक चक्र तत्वों का एक सबसेट है जो एक दूसरे के लिए मैप करता है। उदाहरण के लिए, 1मैप किया जाता है 5, जिसे मैप किया जाता है 6, जिसे वापस मैप किया जाता है 1। तो एक चक्र है [1,5,6]। अन्य चक्र हैं [2]और [3,4]। इस प्रकार इस क्रमपरिवर्तन के लिए चक्रों की संख्या है 3

सामान्य तौर पर, एक क्रमचय के चक्र अद्वितीय होते हैं (ऑर्डर करने के लिए), और आकार के क्रमचय के लिए चक्रों की संख्या nभिन्न होती 1है n

चुनौती

एक गैर-खाली क्रमचय को देखते हुए, इसके चक्रों की संख्या का उत्पादन।

इनपुट एक सरणी द्वारा गठित है nपूर्णांकों 1, 2, ..., n, जहां n > 0। प्रत्येक पूर्णांक ठीक एक बार होता है। जिस क्रम में वे दिखाई देते हैं वह क्रमांकन को परिभाषित करता है, जैसा कि ऊपर दिए गए उदाहरण में है।

एक सरणी के बजाय आप एक सूची, संख्याओं के बीच एक विभाजक के साथ एक स्ट्रिंग, प्रत्येक नंबर के लिए एक अलग इनपुट या उचित है।

आकार के क्रमपरिवर्तन के लिए n, पूर्णांक के 1-आधारित सेट के बजाय 1, ..., nआप लगातार 0-आधारित सेट 0, ..., का उपयोग कर सकते हैं n-1। यदि हां, तो कृपया अपने उत्तर में इसका संकेत दें।

एक समय से कम कहने पर कोड को उचित समय nतक काम करना चाहिए 20

कोड गोल्फ। सभी भवन निर्माण की अनुमति दी।

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

यह 1-आधारित, सरणी इनपुट मानता है।

 [1] -> 1
 [3,2,1] -> 2
 [2,3,4,5,1] -> 1
 [5,2,4,3,6,1] -> 3
 [8,6,4,5,2,1,7,3] -> 2
 [4,5,11,12,7,1,3,9,10,6,8,2] -> 1
 [4,2,5,11,12,7,1,3,9,10,6,8] -> 5
 [5,8,6,18,16,9,14,10,11,12,4,20,15,19,2,17,1,13,7,3] -> 3
 [14,5,17,15,10,18,1,3,4,13,11,16,2,12,9,7,20,6,19,8] -> 7

सम्बंधित

यह संबंधित चुनौती क्रमांकन के वास्तविक चक्रों की मांग करती है, उनकी संख्या नहीं। केवल चक्रों की संख्या की आवश्यकता से छोटे एल्गोरिदम हो सकते हैं जो वास्तविक चक्रों को उत्पन्न करते हैं।


मेरे सवाल पर कोई बात नहीं, यह कहा गया है कि प्रश्न 0-आधारित इनपुट की अनुमति है।
orlp

@orlp जो जल्दी था! मुझे आपका प्रश्न भी देखने को नहीं मिला
लुइस मेंडो

क्या हम इनपुट के रूप में मानों की अनुक्रमणिका का मानचित्रण कर सकते हैं?
कॉपर

1
@Copper मुझे लगता है कि हां, यदि मैपिंग का डोमेन उस क्रम में 1, ..., सेट है n। क्या आप स्पष्ट कर सकते हैं कि मानचित्रण एक इनपुट कैसे हो सकता है? क्या यह डेटा संरचना है?
लुइस मेंडो

@LuisMendo हाँ, यह एक पायथन की तरह एक डेटा संरचना है dict। मैं {1: 2, 2: 1}इसके बजाय एक इनपुट के रूप में होना चाहता हूं [2, 1]
कॉपर

जवाबों:


12

जे, 4 बाइट्स

#@C.

यह मानता है कि क्रमपरिवर्तन 0-आधारित है। यह बिलिन का उपयोग करता है C.जो एक प्रत्यक्ष क्रमपरिवर्तन का प्रतिनिधित्व करने वाली सूची देता है जो चक्रों की सूची का उत्पादन करता है। फिर #रचना की@ है कि उस सूची में चक्र की संख्या रिटर्न पर।

इसे यहाँ आज़माएँ।


1
यह बेइमानी है! :)
orlp 23

1
मुझे बिल्डिंस पर प्रतिबंध लगा देना चाहिए था :
लुइस मेंडो

2
निर्मित प्रेम हैं। निर्मित जीवन हैं। मैं मानता हूं कि यह बिलिन पर प्रतिबंध लगाने के साथ अधिक मजेदार होगा। बहुत सारे जवाब से पहले अभी नियम बदलने के लिए स्वतंत्र महसूस करें।
मील

@ मीलों नाह, मैं इसे वैसे ही छोड़ दूँगा। बहुत बढ़िया!
लुइस मेंडो

7

जावास्क्रिप्ट, 99 98 बाइट्स

यह समाधान सरणी मानता है और इसके मान शून्य-अनुक्रमित (जैसे [2, 1, 0]) हैं।

f=a=>{h={},i=c=0;while(i<a.length){s=i;while(!h[i]){h[i]=1;i=a[i]}c++;i=s;while(h[++i]);}return c}

व्याख्या

// assumes the array is valid and zero-indexed
var findCycles = (array) => {
    var hash = {};  // remembers visited nodes
    var index = 0;  // current node
    var count = 0;  // number of cycles
    var start;      // starting node of cycle

    // loop until all nodes visited
    while(index < array.length) {
        start = index;  // cache starting node

        // loop until found previously visited node
        while(!hash[index]) {
            hash[index] = 1;    // mark node as visited
            index = array[index];   // get next node
        }
        count++;    // increment number of cycles

        index = start + 1;  // assume next node is right after

        // loop until found unvisited node
        while(hash[index]) {
            index++;    // get next node
        }
    }

    return count;   // return number of cycles
};

3
PPCG में आपका स्वागत है! अच्छा पहला जवाब! यह भी सबसे अच्छा में से एक है, अगर सबसे अच्छा नहीं है, तो पहले जवाब मैंने अपने अनुभव में देखा है! अच्छा काम करते रहें!
GamrCorps

वाह बहुत - बहुत धन्यवाद! मुझे वास्तव में देखना था कि जावास्क्रिप्ट में लैम्ब्डा कैसे करें। मैं अभी तक ES6 सामान से परिचित नहीं हूँ।
kamoroso94

6

गणितज्ञ, 45 बाइट्स

Length@ConnectedComponents@Thread[Sort@#->#]&

यह एक ग्राफ बनाता है और इसके जुड़े घटकों को गिनता है।


6

गणितज्ञ, ३। 37 27 बाइट्स

#~PermutationCycles~Length&

9 बाइट बचाने के लिए @alephalpha और 1 और बाइट के लिए @ मीलों धन्यवाद।


3
PermutationCycles[#,Length]&
alephalpha

3
ओह, यह साफ है। मुझे नहीं पता था कि PermutationCyclesइसके उत्पादन के प्रमुख को बदलने के लिए एक दूसरा तर्क हो सकता है। आप एक और बाइट को बचाने के लिए infix संकेतन का उपयोग कर सकते हैं #~PermutationCycles~Length&
मील

1
इसके अलावा अपने मूल समाधान के बारे में, #&की तुलना में काफी कम है Identity। ;)
मार्टिन एंडर

6

पायथन, 77 69 67 बाइट्स

f=lambda p,i=1:i and0 **p[i-1]+f(p[:i-1]+[0]+p[i:],p[i-1]or max(p))

(not p[i-1])के रूप में किया जा सकता है0**p[i-1]
xnor

5

जेली, 12 10 9 बाइट्स

ị³$ÐĿ«/QL

@ डेनिस को 1 बाइट धन्यवाद दिया ।

यह 1-आधारित क्रमपरिवर्तन का उपयोग करता है। यह क्रमपरिवर्तन को बार-बार लागू करने तक काम करता है जब तक कि यह अपने पिछले मूल्यों को बनाए रखते हुए पिछले क्रमपरिवर्तन तक नहीं पहुंच जाता है। परिवर्तनों पर नज़र रखने से, यह उस तालिका के स्तंभों के साथ प्रत्येक मान के लिए कक्षा बनाएगा। फिर, प्रत्येक कॉलम का न्यूनतम या अधिकतम पता लगाकर, उस चक्र के लिए एक लेबल बनाया जा सकता है। फिर लेबल की उस सूची को डुप्लिकेट करें और उसकी लंबाई प्राप्त करें जो कि असंतुष्ट चक्रों की संख्या होगी।

इसे यहाँ आज़माएँ।

व्याख्या

ị³$ÐĿ«/QL  Input: permutation p
  $        Chain (ị³) as a monad
 ³           The input p
ị            For each value x, get the value at index x in p
   ÐĿ      Invoke it on p initially, and repeat it on its next value until it returns
           to a previous value and keep track of the results
           This will create a table where each column is the orbit of each value
     «/    Get the minimum value along each column of that table
       Q   Deduplicate
        L  Get the length and return

बहुत अच्छा तरीका!
लुइस मेंडू

ị³$ÐĿ«/QLकार्य करना चाहिए।
डेनिस

@ डेनिस वाह, यह एक साफ-सुथरी चाल है! चूंकि प्रत्येक चक्र तिरस्कृत है, इसलिए अधिकतम / मिनट लेना और लेबल के रूप में उपयोग करना परिणाम के लिए + लंबाई को कम करने के लिए पर्याप्त होगा।
मील

5

पायथन, 64 बाइट्स

l=input()
for _ in l:l=[min(x,l[x])for x in l]
print len(set(l))

यह गोल्फ कोड मुहावरेदार और पठनीय होता है। 0-इंडेक्सिंग का उपयोग करता है।

प्रत्येक मान यह देखता है कि यह किस ओर इंगित करता है और इंगित मूल्य किसको इंगित करता है, और दोनों के छोटे को इंगित करता है। पर्याप्त पुनरावृत्ति के बाद, प्रत्येक तत्व अपने चक्र के सबसे छोटे तत्व को इंगित करता है। निर्दिष्ट तत्वों की संख्या चक्र की संख्या है।

यह nपुनरावृत्तियों को करने के लिए पर्याप्त है । वैकल्पिक रूप से, हम तब तक पुनरावृति कर सकते हैं जब तक कि सूची में परिवर्तन न हो। इस रणनीति ने मुझे एक ही लंबाई, 64 बाइट्स का पुनरावर्ती कार्य दिया:

f=lambda l,p=0:len(set(l*(l==p)))or f([min(x,l[x])for x in l],l)

65 बाइट्स को कम करना था

lambda l:len(set(reduce(lambda l,_:[min(x,l[x])for x in l],l,l)))

set(_)रूपांतरण करने के लिए छोटा किया जा सकता {*_}अजगर 3.5 में, 2 बाइट्स बचत।


4

हास्केल, 111 बाइट्स

l!i|l!!i<0=l|1<2=(take i l++[-1]++drop(i+1)l)!(l!!i)
f(x:y)|x>=0=0|1<2=1+f y
c l|l==[-1|x<-l]=0|1<2=1+c(l!f l)

0-आधारित अनुक्रमण का उपयोग करता है


4
लानत है, आपके पास बेहतर प्रोग्रामिंग फॉन्ट है :)1l!i|iIi!!1ll1|
orlp

@orlp और यह 111 बाइट्स है! : O
ग्रूव्प्लेक्स

4

अजगर, 9 बाइट्स

l{mS.u@QN

0-आधारित इंडेक्स का उपयोग करता है। इसे ऑनलाइन आज़माएं

यह काम किस प्रकार करता है

  m         map for d in input:
    .u        cumulative fixed-point: starting at N=d, repeatedly replace N with
      @QN       input[N]
              until a duplicate is found, and return all intermediate results
   S          sort
 {          deduplicate
l           length

3

जावास्क्रिप्ट (ईएस 6), 49 बाइट्स

a=>a.reduce(g=(c,e,i)=>e<i?g(c,a[e],i):c+=e==i,0)

शून्य-आधारित अनुक्रमण का उपयोग करता है। स्पष्टीकरण: सरणी के प्रत्येक तत्व पर reduceआंतरिक फ़ंक्शन को लागू करने के लिए उपयोग किया जाता है gcचक्रों की गिनती eहै, सरणी तत्व iहै, सरणी सूचकांक है। यदि तत्व सूचकांक से कम है, तो यह एक संभावित चक्र है - तत्व का उपयोग अनुक्रमणिका में अगले तत्व को खोजने के लिए सरणी में अनुक्रमित करने के लिए किया जाता है। यदि हमने मूल सूचकांक के साथ शुरुआत या अंत किया है तो यह एक नया चक्र है और हम चक्र गणना में वृद्धि करते हैं। यदि किसी भी बिंदु पर हम सूचकांक से बड़ा मान पाते हैं तो हम उस चक्र को बाद में गिनेंगे।


जब मैंने सरणी पर आपका कोड चलाया [2,1,0,3,4,5] , तो यह इस संदेश के साथ क्रैश हो गया "अधिकतम कॉल स्टैक आकार पार हो गया"।
kamoroso94

1
@ kamoroso94 इसके बारे में क्षमा करें, एक टाइपो ने क्रेप किया था। अब इसे ठीक किया जाना चाहिए।
नील

2

सी, 90 बाइट्स

कॉल f()एक परिवर्तनशील intसरणी, 1 आधारित अनुक्रमण के साथ । दूसरा पैरामीटर सरणी का आकार है। फ़ंक्शन चक्र की संख्या लौटाता है।

i,j,c;f(a,n)int*a;{for(c=i=0;i<n;++i)for(j=0,c+=!!a[i];a[i];a[i]=0,i=j-1)j=a[i];return c;}

इसे आइडोन पर आज़माएं

एल्गोरिथ्म:

For each index
    If index is non-zero
        Increment counter
        Traverse the cycle, replacing each index in it with 0.

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.