একটি অনুক্রমের চক্রের সংখ্যা


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

সম্পর্কিত

এই সম্পর্কিত চ্যালেঞ্জটি ক্রমটির প্রকৃত চক্রের জন্য জিজ্ঞাসা করে, তাদের সংখ্যা নয়। শুধুমাত্র চক্রের সংখ্যার প্রয়োজন হলে সংক্ষিপ্ত অ্যালগোরিদম হতে পারে যা আসল চক্র উত্পন্ন করতে পারে sides


আমার প্রশ্নটি মনে রাখবেন না, এটি 0-ভিত্তিক ইনপুট অনুমোদিত প্রশ্নে বলা হয়েছে।
orlp

@orlp তাড়াতাড়ি ছিল! আমি আপনার প্রশ্নটি দেখতে পেলাম না
লুইস মেন্ডো

আমরা কি ইনপুট হিসাবে মানগুলিতে সূচকের ম্যাপিং নিতে পারি?
তামা

1
@ কপার আমি হ্যাঁ মনে করি, যদি ম্যাপিংয়ের ডোমেনটি সেট হয় 1, ..., nএই ক্রমে। আপনি কী ব্যাখ্যা করতে পারেন যে ম্যাপিং কীভাবে ইনপুট হতে পারে? এটি কি ডেটা স্ট্রাকচার?
লুইস মেন্ডো

@ লুইস মেন্ডো হ্যাঁ, এটি একটি ডেথ কাঠামো, পাইথনের মতো dict। আমি {1: 2, 2: 1}পরিবর্তে একটি ইনপুট হিসাবে পেতে চাই [2, 1]
কপার

উত্তর:


12

জে, 4 বাইট

#@C.

এটি অনুমান করে যে অনুমতিটি 0-ভিত্তিক। এটি অন্তর্নির্মিত ব্যবহার করে C.যা প্রত্যক্ষ ক্রিয়াকলাপ উপস্থাপন করে এমন একটি তালিকা দেয় যা চক্রের একটি তালিকা দেয়। তারপরে #রচনাটি @সেই তালিকার চক্রের সংখ্যা প্রদান করে।

এখানে চেষ্টা করুন।


1
এটাই প্রতারণা! :)
orlp

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
পিপিসিজিতে আপনাকে স্বাগতম! প্রথম উত্তর! এটিও অন্যতম সেরা, যদি সেরা না হয় তবে প্রথম উত্তরটি আমি আমার অভিজ্ঞতায় দেখেছি! ভাল কাজগুলো করতে থাকো!
GamrCorps

বাহ, আপনাকে অনেক ধন্যবাদ! আমি আসলে জাভাস্ক্রিপ্টে ল্যাম্বডাস কীভাবে করব তা সন্ধান করতে হয়েছিল। আমি এখনও ES6 স্টাফের সাথে তেমন পরিচিত নই।
কামোরসো94 4

6

গণিত, 45 বাইট

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

এটি একটি গ্রাফ উত্পন্ন করে এবং এর সাথে সংযুক্ত উপাদানগুলি গণনা করে।


6

গণিত, 37 28 27 বাইট

#~PermutationCycles~Length&

9 বাইট, এবং আরও 1 বাইটের জন্য @ মাইলস সঞ্চয় করার জন্য @ আলেফাল্ফাকে ধন্যবাদ।


3
PermutationCycles[#,Length]&
আলেফাল্ফ

3
ওহ যে ঝরঝরে। আমি জানতাম না যে PermutationCyclesএর আউটপুটটির মাথা বদল করতে দ্বিতীয় যুক্তি নিতে পারে। আপনি অন্য বাইট সংরক্ষণ করতে ইনফিক্স স্বরলিপি ব্যবহার করতে পারেন #~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-ইনডেক্সিং ব্যবহার করে।

প্রতিটি মান এটি কীটি নির্দেশ করে এবং কীসের নির্দেশিত মানটি নির্দেশ করে এবং দুটিটির আরও ছোট দিকে নির্দেশ করে at পর্যাপ্ত পুনরাবৃত্তির পরে, প্রতিটি উপাদান তার চক্রের ক্ষুদ্রতম উপাদানের দিকে নির্দেশ করে। স্বতন্ত্র উপাদানের সংখ্যা নির্দেশ করে তখন চক্রের সংখ্যা।

এটা করা যথেষ্ট n পুনরাবৃত্তি ices বিকল্পভাবে, তালিকাটি আর পরিবর্তন না হওয়া পর্যন্ত আমরা পুনরাবৃত্তি করতে পারি। এই কৌশলটি আমাকে একই দৈর্ঘ্যের একটি পুনরাবৃত্ত ফাংশন দিয়েছে, 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

পাইথ, 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

জাভাস্ক্রিপ্ট (ES6), 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 এর জন্য দুঃখিত, একটি টাইপো প্রবেশ করেছিল now এখনই ঠিক করা উচিত।
নিল

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.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.