লুপ সনাক্তকরণ - ধরণের নয়!


24

এই চ্যালেঞ্জের লক্ষ্য হ'ল লুপ দ্বারা আবদ্ধ দিক এবং অঞ্চলটি সন্ধান করা।

ইনপুট:

একটি আয়তক্ষেত্রাকার গ্রিড যা সম্পূর্ণরূপে এই অক্ষরগুলির সমন্বয়ে থাকে: ^v<>

(Allyচ্ছিকভাবে, আপনাকে গ্রিডের দশমিক অর্থে নিজের পছন্দসই একটি উপসর্গ, প্রত্যয় এবং বিভাজক চরিত্র সহ গ্রিডের মাত্রাগুলিও দেওয়া যেতে পারে))

গ্রিডের একটি লুপ পূর্বোক্ত বর্ণগুলির একটি সেট যা একের পরের দিকে নির্দেশ করে, পরের দিকে নির্দেশ করে, অবশেষে প্রথম অক্ষরটির দিকে ফিরে নির্দেশ করে। উদাহরণ স্বরূপ:

<>>v>     >>v 
^^<>v     ^ >v
>^<<<     ^<<<
>^<v>         

বাম গ্রিডটি নমুনা ইনপুট; ডান গ্রিড লুপ বিচ্ছিন্ন হয়।

ইনপুট গ্রিডে হয় কোনও লুপ বা এক লুপ থাকবে না; গ্রিডে একাধিক লুপ রয়েছে এমন কোনও ক্ষেত্রে আপনাকে চিন্তার দরকার নেই।

আউটপুট:

যদি গ্রিডে কোনও লুপ না থাকে তবে আউটপুট X

যদি গ্রিডে একে অপরের দিকে নির্দেশ করে দুটি তীর থাকে তবে আউটপুট 0

যদি গ্রিডে একটি ঘড়ির কাঁটার বিপরীতে লুপ থাকে তবে সীমান্ত সহ লুপ দ্বারা আবদ্ধ অক্ষরগুলি গণনা করুন। আউটপুট যে নম্বর।

যদি গ্রিডটিতে একটি ক্লকওয়াস লুপ থাকে তবে কাউন্টার ক্লকওয়াস লুপের জন্য একই প্রক্রিয়াটি অনুসরণ করুন, তবে সেই সংখ্যার নেতিবাচক আউটপুট দিন। উদাহরণস্বরূপ, উপরের ইনপুট গ্রিডটির আউটপুট থাকবে -11: 10 লুপ থেকে আসে এবং লুপ দ্বারা আবদ্ধ অক্ষর থেকে 1।

এটি । সংক্ষিপ্ততম কোড জিতেছে।

পরীক্ষার কেস:

<<^
^>v
^v<

আউটপুট X

<<<<
><<<
>>^>

আউটপুট 0

<>^^<
>>>v>
<^^>v
<^>>v
>^<<<

আউটপুট -15

v<<<<
>v>>^
v<^<<
>>>>^

আউটপুট 20


4
ডাউনভোটস কেন? প্রশ্নটি আমার কাছে ভাল লাগছে।
xnor

আপনি কীভাবে নির্ধারণ করবেন যে কোনও লুপটি ঘড়ির কাঁটার দিকে আছে কিনা? উদাহরণস্বরূপ, গুগল চিত্রগুলিতে "ডাবল সর্পিল গোলকধাঁধা" অনুসন্ধান করুন। আপনি কীভাবে নির্ধারণ করবেন যে কোন পথে চলছে? এখানে একটি উদাহরণ।
ভূত_স_ই_কোড

@Gosts_in_t__code যা কোনও বদ্ধ লুপ তৈরি করে না।
মার্টিন ইন্ডার

@ মার্টিনব্যাটনার একে অপরের সাথে সংযোগ স্থাপনের জন্য বাইরের দুটি প্রান্তটি কল্পনা করুন।
ভুতগুলি_ইন_কোড

4
@Gosts_in_the_code তারপরে একটি প্রান্তটি ঘুরে আবার অপরটির সাথে দেখা করতে হবে। সেক্ষেত্রে আপনি একটি চৌরাস্তা মুক্ত লুপ পাবেন যা এটি ঘড়ির কাঁটার দিকে বা ঘড়ির কাঁটার দিকে চলছে কিনা তা দেখানোর জন্য একটি বৃত্তে প্রকাশিত হতে পারে। একটি সহজ পরীক্ষা হ'ল লুপের নীচের অংশের নীচের অংশটি দেখুন এবং এটি বাম বা ডানদিকে চলেছে কিনা তা পরীক্ষা করা (গ্রিডের ক্ষেত্রে, পয়েন্টটি অনন্য নয়, তবে আপনি নীচের ডানদিকের সবচেয়ে ঘরের দিকে তাকান লুপটি পরীক্ষা করে দেখুন যে এটি বাম বা উপরে যাচ্ছে কিনা)।
মার্টিন ইন্ডার

উত্তর:


4

সি #, 604 বাইট

সম্পূর্ণ প্রোগ্রাম, এসটিডিআইএন থেকে ইনপুট (লাইন-বিস্মৃত বিন্যাস, কোনও মাত্রা নেই) গ্রহণ করে, এসটিডিআউট-এ আউটপুট দেয়।

using C=System.Console;class P{static void Main(){int w=0,W,i,j,t,k,l,c;string D="",L;for(;(L=C.ReadLine())!=null;D+=L)w=L.Length;var R=new[]{-1,0,1,w,-w};L="X";for(W=i=D.Length;i-->0;){var M=new int[W];for(k=j=i;i>0;){M[j]=++k;t=j+R[c=D[j]%5];if(t<0|t>=W|c<3&t/w!=j/w|c>2&t%w!=j%w)break;j=t;if((l=M[j])>0){var J=new int[W+1];System.Func<int,int>B=null,A=s=>J[s]<0?0:J[k=B(s)]=k==W?k:i;B=x=>J[x]==x?x:B(J[x]);for(i=J[W]=W;i>0;)J[--i]=M[i]<l?i%w<1|i%w>w-2|i<w|i>W-w?W:i:-1;for(;i<W;)if(J[++i]<0)l=D[i]%5/2-1;else{A(i-1);if(i>w)A(i-w);}for(c=W;i-->0;L=""+(c>2?c:0)*l)c-=J[i]<0?0:B(i)/W;}}}C.WriteLine(L);}}

প্রোগ্রামটি প্রথমে বিন্যাসে পড়া, বলা বাহুল্য, এবং তারপরে প্রতিটি কক্ষে পুনরাবৃত্তি করে কাজ করে। তারপরে আমরা প্রতিটি কক্ষ থেকে একটি 'সাপ' চালাই, যা তীরটি প্রান্ত থেকে চালা না হওয়া বা নিজের মধ্যে না চলে অবধি অনুসরণ করে। যদি এটি নিজের মধ্যে চলে যায়, তবে আমরা জানি যে আমরা একটি লুপ পেয়েছি (বা এর মধ্যে একটি "> <" জিনিস), এবং এটিও জানে যে সাপটি লুপে রয়েছে।

একবার আমরা যখন জানতে পারি যে আমাদের একটি লুপ রয়েছে, তখন আমরা জানি যে কোন কোষটি লুপে রয়েছে এবং আমরা প্রতিটি কক্ষ থেকে একটি মানচিত্র তৈরি করি (+1, কারণের জন্য) নিজেই হয়, -1(এর অর্থ এটি লুপের উপরে), বা W(পুরো প্রস্থ) যদি বিষয়টিকে Wআরও সহজ করার জন্য এটি প্রান্তে থাকে (বা +1 (যা সূচকে রয়েছে ))

আমরা এটি করার সময়, আমরা লুপটির 'শেষ' উপাদানটির দিকও খুঁজে পাই (এটি, শেষ সারিটির লুপের শেষ উপাদানটিতে লুপ থেকে উপাদান রয়েছে)। এই উপাদানটি অবশ্যই একটি "<" বা "^" হওয়া উচিত এবং এটি আমাদেরকে লুপটির ঘড়ির ঘনত্ব (সিডাব্লু / সিসিডাব্লু) (-1 / + 1 তে অনুবাদ করে) বলে tells

তারপরে আমরা একটি বিচ্ছিন্ন সেট পাস করব, যা লুপের বাইরে থাকা সমস্ত উপাদানকে Wসেট করে। এরপরে এবং লুপটিতে Wথাকা সংখ্যাটি পেতে এইগুলির মধ্যে কতগুলি রয়েছে তা আমরা বিয়োগ করি । যদি এই সংখ্যাটি 3 এর চেয়ে কম হয় তবে আমরা 0 দিয়ে এটি প্রতিস্থাপন করব We আমরা এটি ঘড়ির সাহায্যে গুণ করব, ফল হিসাবে সেট করব এবং কোনওভাবে লুপের জন্য এড়িয়ে চলেছি, যেখানে ফলাফল আউটপুট।

তবে, উপরের অংশগুলির বেশিরভাগটি কখনই ঘটে না (কারণ কোনও সাপ কখনই নিজেকে আবিষ্কার করে না), তবে ফলাফলটি "এক্স" হিসাবে থাকে এবং এটি আউটপুট হয়।

using C=System.Console;

class P
{
    static void Main()
    {
        int w=0, // width
        W, // full length
        i, // used for iterating over all the cells
        j, // keeps track of where the snake as got to
        t, // t is next j
        k, // how far along the snake we are, kind of
        // later on, k is used as temp for A
        l, // stores a threshold for how far along the snake the loop starts
        // later on, l stores the last seen pointer - this tells us the clockness
        c; // the translated direction
        // later on, c is a backwards-count

        string D="", // D is the map
        L; // used for reading lines, and then storing the result

        // might not be the best yay of doing this
        for(;(L=C.ReadLine())!=null; // read a line, while we can
            D+=L) // add the line to the map
            w=L.Length; // record the width

        var R=new[]{-1,0,1,w,-w}; // direction table (char%5) - might be able to replace this array with some bit bashing/ternary

        L="X"; // can't seem to fit this in anywhere... (don't strictly need to re-use L)
        for(W=i=D.Length;i-->0;) // for each cell, we send a 'snake' to try to find the loop from that cell
        {
            var M=new int[W]; // stores how far along the snake this point is

            for(k=j=i; // k's value doesn't really matter, as long as it's not stupidly big
                i>0;) // the i>0 check is just for when we return (see comment at the end of the code)
            {
                M[j]=++k; // store snake point and advance distance

                t=j+R[c=D[j]%5]; // t is position after move (translate <>v^ to 0234 (c is direction))
                //c=D[j]%5; // translate <>v^ to 0234 (c is direction)
                //t=j+R[c]; // t is position after move
                if(t<0|t>=W|c<3&t/w!=j/w|c>2&t%w!=j%w)
                    break; // hit an edge - will always happen if we don't find a loop - give up on this snake
                j=t; // move to new position

                if((l=M[j])>0) // we've been here before...
                {
                    // disjoint sets (assign all the edges to one set, assign all the ones on the line to another set, do adjacent disjoint, return size-outteredge (minus if necessary)
                    var J=new int[W+1]; // looks like we can reuse M for this

                    System.Func<int,int>B=null,
                    // whatever s points at should point to i, unless s points to W, in which case it should keep point to W
                    A=s=>J[s]<0?0:J[k=B(s)]=k==W?k:i;
                    // read the value this points to
                    B=x=>J[x]==x?x:B(J[x]);

                    for(i=J[W]=W;i>0;)
                        J[--i]=M[i]<l? // if we are not part of the loop
                            i%w<1|i%w>w-2|i<w|i>W-w? // if we are on the edge
                                W: // on the edge
                                i: // not on the edge
                             -1; // this is on the loop

                    // now fill in
                    // we don't have to worry about wrapping, the important bit being an un-wrapping closed loop
                    // i = 0
                    for(;i<W;)
                        if(J[++i]<0) // we are on the loop
                            l=D[i]%5/2-1; // last one must be ^(4) or <(0)
                        else{ // can probably crush this into an l returning l assigning term (with if above)
                            A(i-1);
                            if(i>w)
                                A(i-w);
                        }

                    // now count the number of non-edges
                    for(c=W; // assume everything is a non-edge
                        i-->0;
                        L=""+(c>2?c:0)*l) // set output to be number of non-edges * clockness (or 0 if too few)
                        c-=J[i]<0?0:B(i)/W; // subtract 1 if an edge (B(i) is W), othewise 0

                    // at this point, i is 0, so we will fall out of all the loops
                }
            }
        }

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