लेजर गंतव्यों से मेल करने के लिए दर्पण कॉन्फ़िगरेशन ढूंढें


13

अद्यतन स्कोरिंग : जैसा कि मैंने चुनौती दी थी, यह चुनौती अधिक कठिन है, मैंने स्कोरिंग को समायोजित किया है। एक प्रोग्राम जो एकल दर्पण इनपुट को हल कर सकता है, एक मान्य उत्तर है। अधिक परिष्कृत कार्यक्रमों से उनके स्कोर को बोनस मिलता है।

पीपीसीजी पर दर्पणों के एक बॉक्स में एक लेजर पथ खोजने के लिए कई पहेलियाँ हैं। इस पहेली में, आपको कई लेजर गंतव्यों से मेल खाने के लिए दर्पण का एक बॉक्स बनाने की आवश्यकता है।

आपको एक बॉक्स और एक विनिर्देश दिया जाता है, जहां पराबैंगनीकिरण प्रवेश करने और बाहर निकलने के लिए होता है। आपके कार्यक्रम को विनिर्देश को पूरा करने के लिए बॉक्स में बिल्कुल एन डबल-पक्षीय दर्पण लगाने की आवश्यकता है। दर्पणों को 45 डिग्री पर कोण होना चाहिए, लेकिन आगे ढलान या पीछे की ओर ढलान हो सकता है।

इनपुट

आपका कार्यक्रम STDIN, कमांड लाइन तर्क, या निम्न प्रारूप उदाहरणों में फ़ाइल के माध्यम से एक बॉक्स ग्रिड को स्वीकार करना चाहिए:

+--G--+     +abcde+
G     |     f/////d
|    /|     a//   c
+-----+     f     |
            +-b-e-+

अक्षर जोड़े ([a-zA-Z] का उपयोग किया जा सकता है) 52 लेज़रों तक के इनपुट / आउटपुट को दर्शाता है। बॉक्स के अंदर N /दर्पण होगा। बॉक्स का आयाम 3 <= W, H <= 200 होगा। बॉक्स +|-पात्रों से बना है । बॉक्स में शून्य सहित दर्पण की संख्या हो सकती है।

उत्पादन

आउटपुट को इनपुट से मेल खाना चाहिए, सिवाय इसके कि /पात्रों को स्थानांतरित किया जा सकता है और / या \पात्रों में परिवर्तित किया जा सकता है । आपके प्रोग्राम को नई लाइन वैकल्पिक करते हुए, STDOUT या फ़ाइल के लिए एक सही मिरर बॉक्स स्ट्रिंग भेजना चाहिए। यदि दर्पण का कोई प्लेसमेंट इनपुट विनिर्देश, आउटपुट को पूरा नहीं कर सकता है Impossible\n। संभावित समाधान के उदाहरण:

+--G--+     +abcde+
G  /  |     f \ \ d
|     |     a/ \  c
+-----+     f / //|
            +-b-e-+

परीक्षण उदाहरण

इनपुट:

+abcdefghijklmnopqrstuvwxyA-+
|///////////////            |
|///////////////            |
|                           |
+-Abcdefghijklmnopqrstuvwxya+

उदाहरण आउटपुट:

+abcdefghijklmnopqrstuvwxyA-+
|\                         \|
|/                        / |
|\\\\\\\\\\\\\\\\\\\\\\\\\\ |
+-Abcdefghijklmnopqrstuvwxya+

स्कोरिंग (अद्यतन)

यह बोनस के साथ कोड-गोल्फ है। आपको अपने जवाब के साथ नामांकित करना चाहिए कि आपका कार्यक्रम कितने दर्पणों को हल कर सकता है (एन)। आपका स्कोर एन द्वारा विभाजित बाइट्स में आपके कार्यक्रम की लंबाई है। यह लोगों को एक साधारण कार्यक्रम के साथ प्रवेश करने की अनुमति देता है, लेकिन बोनस के साथ अधिक महत्वाकांक्षा प्रोग्रामर को पुरस्कृत करता है।

मानक खामियों को दूर किया।


3
यह गोल्फिंग की परवाह किए बिना एक कठिन समस्या की तरह लगता है।
orlp

2
संकेत: जानवर बल एक विकल्प नहीं है ; यह आपको बड़े उदाहरण के लिए 10 सेकंड के विकल्प पर 3 ब्रह्मांड उम्र ले जाएगा।
Sanchises

@ मैं यह सोचता हूँ कि इसमें बहुत समय लगेगा, क्योंकि कोई भी दर्पण फ़्लिप किया जा सकता है, इसलिए मुझे लगता है कि आपको * 2^30वहाँ एक घटक की भी आवश्यकता है
विजुअलमेलन

अतिरिक्त संकेत: आपको अपने खोज स्थान को प्रिंय करने के लिए पहेली के गुणों का दोहन करने की आवश्यकता होगी। आप आंशिक समाधानों के संयोजन का उपयोग भी कर सकते हैं या आंशिक समाधानों से हिलक्लाइंबिंग कर सकते हैं जो एक पूर्ण समाधान के करीब हैं। यह अब सरल समाधान के साथ जवाब देने के लिए मान्य है, इसलिए एक या दो दर्पण पहेली को हल करने वाले कार्यक्रमों का भी स्वागत है।
लॉजिक नाइट

जवाबों:


2

सी # - 897 862 बाइट्स

इसके साथ एक गंभीर बग मिला जिसमें उन स्थानों पर दर्पण लगाए गए हैं जो वे नहीं हो सकते। अब यह काम करता है, उम्मीद है! कुछ हल्की गोल्फिंग भी की, जबकि लूप को वहां नहीं छोड़ा जा सका ... शर्मनाक।

पूरा कार्यक्रम, STDIN से इनपुट लेता है, STDOUT को आउटपुट देता है।

यह बहुत मज़ा था, यह 7 से 5 समस्या के साथ ठीक हो जाता है (और जब आप दर्पण में से एक को हटाते हैं, तो यह असंभव बना देता है), 30 को 5 द्वारा हल करने में लगभग 1 घंटे का समय लगा।

using Q=System.Console;class P{static int w,L;static string S(char[]M,int t,int r,int i,int d,int[]B){var s="";if(r<0)return s;M=(char[])M.Clone();B=(int[])B.Clone();B[i]=1;for(i+=d;M[t]<48|t==i;i=t+(d=t<w?w:t>L-w?-w:t%w<1?1:-1))if(++t>=L){for(i=0;++i<L&r>0;)if(B[i]<1&M[i]<33){M[i]='.';r--;}return r<1?new string(M):s;}int c=M[i];if(c>32)s=c>47|c<46?s=c==M[t]?S(M,t,r,t,0,B):s:S(M,t,r,i,c<47?w/d:-w/d,B);else if((s=S(M,t,r,i,d,B))==""&B[i]<1){M[i]='.';s=S(M,t,r-1,i,w/d,B);if(s==""){M[i]='/';s=S(M,t,r-1,i,-w/d,B);}}return s;}static void Main(){string a,A="",R=A;for(;(a=Q.ReadLine())!=null;A+=a)L+=(w=a.Length);var G=A.ToCharArray();int r=0,i=L;for(;i>0;G[i]=G[i]=='|'?',':G[i])if(G[--i]==47|G[i]==92){r++;G[i]=' ';}a=S(G,0,r,1,w,new int[L]);if(a=="")R="Impossible\n";else for(;i<L;i+=w)R+=a.Substring(i,w)+"\n";Q.Write(R.Replace(".","\\").Replace(",","|"));}}

7 द्वारा 5 उदाहरण:

+abcde+
f/////d
a//   c
f     |
+-b-e-+

+abcde+
f   \ d
a/  //c
f/ \ /|
+-b-e-+

असंभव संस्करण:

+abcde+
f ////d
a//   c
f     |
+-b-e-+

Impossible

कुछ अलग है (कार्यक्रम मूल दर्पण लेआउट को नहीं देखता है):

+a----+
|//// |
|/////|
|/////|
+----a+

+a----+
| /\\\|
|\\\\\|
|\\/\\|
+----a+

5 समाधान द्वारा 30:

+abcdefghijklmnopqrstuvwxyA-+
| \\\\\\\\\\\\\\\\\\\\\\\\ \|
| /                       //|
|\                         \|
+-Abcdefghijklmnopqrstuvwxya+

यह बदले में प्रत्येक लेजर स्रोत को देखता है, और इसके लिए एक वैध मार्ग बनाता है (यदि यह हो सकता है), और फिर अगले पर चलता है। यह एक बहुत ही सरल गहराई-पहली खोज है, जिसे यह जानना है कि यह किस लेजर स्रोत (लक्ष्य) को देख रहा है, इसे लगाने के लिए कितने दर्पण हैं, वर्तमान सेल यह "पर" है, जिस दिशा में यह बढ़ रहा है और प्रत्येक सेल यह पहले से ही दौरा किया है (ताकि यह एक दर्पण नहीं रखता है कहीं यह पहले से ही है)। अंतिम 3 का उपयोग वर्तमान लक्ष्य के लिए पथ कोडांतरण के लिए किया जाता है, और लक्ष्य बदलने पर रीसेट किया जाता है। एक बार जब यह सभी लेज़रों को जोड़ दिया जाता है, तो यह आगे बढ़ता है और किसी भी अंतराल में भर जाता है, इसे खाली नहीं छोड़ा जाता है (एक अन्य कारण यह हर जगह यह जानने की आवश्यकता है कि यह दौरा किया गया है)।

जब यह मार्गों का निर्माण कर रहा है, तो यह दर्पण डालने पर "आगे" जाने का पक्षधर है, और जब यह करता है, तो यह "\" दर्पण का पक्ष लेता है - यह सबसे ऊपर "कुछ अलग" उदाहरण में देखा जाता है, जहां यह नीचे की पहली सेल को छोड़ देता है शीर्ष-सबसे 'a', तो लगातार एक "\" भरता है अगर वह एक के साथ एक समाधान पा सकता है, अन्यथा "/" (स्वाभाविक रूप से, अगर पहली सेल को छोड़ दें तो परिणामस्वरूप समाधान खोजने में असमर्थ रहा, तो यह होगा बैक-ट्रैक (इसके बजाय दर्पण लगाने का प्रयास करें)।

using Q=System.Console;

class P
{
    static int w,L;

    // M is cur grid
    // t is target edge thing (0->L)
    // r is mirrors remaining
    // i is pos
    // d is dir
    static string S(char[]M,int t,int r,int i,int d,int[]B)
    {
        var s="";

        if(r<0) // no mirrors left
            return s;

        // clone everything
        M=(char[])M.Clone();
        B=(int[])B.Clone();

        B[i]=1; // can't write to this

        for(i+=d; // move i
            M[t]<48|t==i; // only if target is something sensible (increment if i==t)
            i=t+(d=t<w?w:t>L-w?-w:t%w<1?1:-1)) // reflect, should be fine for w=3
            if(++t>=L) // run off the end
            {
                for(i=0;++i<L&r>0;) // don't need I any more (count through everything)
                    if(B[i]<1&M[i]<33) // not been here & it's open space
                    {
                        M[i]='.'; // doesn't matter
                        r--;
                    }
                return r<1?new string(M):s; // none remaining ? victory : defeat
            }

        int c=M[i];
        if(c>32) // not boring
            s=c>47|c<46? // hit edge
                s=c==M[t]? // hit the correct thing
                    S(M,t,r,t,0,B): // i+0=t, tells it to increment t
                    s
            :S(M,t,r,i,c<47?w/d:-w/d,B); // mirror
        else // boring
            if((s=S(M,t,r,i,d,B))==""&B[i]<1) // fwd
            {
                M[i]='.'; // use . instead of \
                s=S(M,t,r-1,i,w/d,B); // \
                if(s=="")
                {
                    M[i]='/';
                    s=S(M,t,r-1,i,-w/d,B); // /
                }
            }

        return s;
    }

    static void Main()
    {
        string a,A="",R=A; // R is free
        for(;(a=Q.ReadLine())!=null;A+=a) // read input
            L+=(w=a.Length); // note width, accumulate length

        var G=A.ToCharArray();

        int r=0,i=L; // count mirrors (I refuse to make these static)
        for(;i>0; // end on i=0
            G[i]=G[i]=='|'?',':G[i]) // replace | with ,
            if(G[--i]==47|G[i]==92) // remove and count mirrors
            {
                r++;
                G[i]=' '; // storing G[i] doesn't seem to save anything
            }

        // search
        a=S(G,0,r,1,w,new int[L]);

        if(a=="") // defeat
            R="Impossible\n";
        else // victory
            for(;i<L;i+=w) // for each line
                R+=a.Substring(i,w)+"\n";

        Q.Write(R.Replace(".","\\").Replace(",","|")); // swap back | and \
    }
}

अच्छा समाधान है। नई स्कोरिंग प्रणाली के अनुसार आप कम से कम 917/7 = 131 स्कोर करते हैं।
लॉजिक नाइट

2

पायथन, 671 654 बाइट्स

समाधान नहीं, बल्कि एक प्रयास, नीचे पढ़ें।

import random as R
def V(F):
 for S,_x,_y in (F[0],0,1),(F[-1],0,-1),([L[0] for L in F],1,0),([L[-1] for L in F],-1,0):
  for i,C in enumerate(S):
   if not C in '+-|':
    x=_x;y=_y
    if not x: X=i;Y=y
    elif not y: Y=i;X=x
    while F[Y][X] != C:
     if F[Y][X]=='\\':x,y=y,x
     if F[Y][X]=='/':a=x+y;x,y=x-a,y-a
     X+=x;Y+=y
     try:
      if F[Y][X] in '+-|':return False
     except:
      return False
 return True
F=open(input()).read().split('\n')
while 1:
 _=[F[0]]+['\n'.join([L[0]+''.join([R.choice(' \\/')for i in range(len(F[0])-2)])+L[-1] for L in F[1:-1]])]+[F[-1]]
 if V(_):
  for l in _: print l
  break

मैंने इसे अधिकतम नहीं किया, क्योंकि मैं समाधान से संतुष्ट नहीं हूं। Vदिए गए Fप्रत्येक वर्ण के लिए फ़ील्ड को चलते हुए दिए गए समाधान को मान्य करता है, जो Cइसे साइडलाइन पर मिलता है। समाधान यादृच्छिक पर उत्पन्न होते हैं। यह बदसूरत है, यह प्रविष्टि 1 के लिए काम करता है, लेकिन अन्य प्रविष्टियों के लिए बहुत समय लगता है। चूंकि यह बेतरतीब ढंग से समाधान की कोशिश करता है, इसलिए मैं इसे दी गई समस्या का वास्तविक समाधान नहीं मानता; लेकिन यह दूसरों की मदद कर सकता है।

Daud: echo "entry1.txt" | python script.py


1
नई स्कोरिंग प्रणाली के साथ, यह एक वैध समाधान है लेकिन एक विभाजक बोनस स्कोर नहीं करता है (जब तक कि यह 2 या अधिक दर्पणों के साथ समस्याओं को हल नहीं कर सकता है)। मुझे लगता है कि आप पहले अमान्य कॉन्फ़िगरेशनों को हटाकर इसे ऑप्टिमाइज़ कर सकते हैं (उदाहरण के लिए: किनारे पर एक अक्षर वाले प्रत्येक स्तंभ या पंक्ति में कम से कम एक दर्पण होना चाहिए - जब तक कि मेल पत्र एक दूसरे के विपरीत न हों)।
लॉजिक नाइट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.