Ais523 के लिए एक BackFlip करो!


16

यह चुनौती " बेस्ट ऑफ़ पीपीसीजी 2016 " में " रूकी ऑफ़ द ईयर " श्रेणी जीतने के लिए ais523 के लिए एक पुरस्कार है । बधाई हो!


बैकफ्लिप उपयोगकर्ता ais523 द्वारा बनाई गई एक गूढ़ प्रोग्रामिंग भाषा है , जिसने 30 से अधिक अन्य रोचक एसोलैंग बनाए हैं

बैकफ्लिप एक 2 डी भाषा है जैसे बेफुंज या > <> जहां निर्देश सूचक पाठ (कार्यक्रम) का एक ग्रिड ट्रेस करता है, ऊपर, नीचे, बाएं और दाएं घूम रहा है, यह उस चरित्र के आधार पर दिशा बदल रहा है। गंभीर रूप से, बैकफ़्लिप कार्यक्रम में ग्रिड बदल जाता है क्योंकि यह लैंग्टन के एंट की तरह थोड़ा पीछे की ओर है ।

इस चुनौती के लिए आप मान सकते हैं कि एक बैकफ़्लिप कार्यक्रम हमेशा पाठ का एक आयताकार ग्रिड होता है (सभी लाइनें समान लंबाई), 1 × 1 आकार में न्यूनतम, केवल अक्षर होते हैं ./\<>^V। ( .अंतरिक्ष के बजाय दृश्यता के लिए उपयोग किया जाता है।) शब्दार्थ बैकफ्लिप हम यहाँ उपयोग करेंगे मूल कल्पना के समान है ।

BackFlip में इंस्ट्रक्शन पॉइंटर (IP) हमेशा प्रोग्राम के ऊपरी-बाएं कोने से दाएं-बाएं से शुरू होता है। इसके तीन प्रकार के कमांड हो सकते हैं:

  1. .एक सेशन नहीं है यह जिस दिशा में जा रहा था उस पर आईपी जारी है। नो-ऑप एक नो-ऑप रहता है।

  2. /और \दर्पण हैं। वे अपने कोण द्वारा इंगित दिशा में आईपी को दर्शाते हैं, फिर वे दूसरे प्रकार के दर्पण में बदलते हैं

    • उदाहरण के लिए, यदि आईपी सिर एक में छोड़ दिया जाता है \, तो यह बाएं की बजाय ऊपर की ओर बढ़ने लगता है और एक \बन जाता है /
  3. <, >, ^, और Vतीर हैं। वे जिस दिशा में इंगित करते हैं उस दिशा में IP को पुनर्निर्देशित करते हैं, फिर वे एक तीर में बदलते हैं जो IP से उस दिशा में इंगित करता है (जिस दिशा में IP चल रहा था उसके विपरीत)

    • उदाहरण के लिए, यदि IP नीचे की ओर जाता है >, तो यह नीचे की बजाय दाएं चलना शुरू कर देता है और क्योंकि IP जिस दिशा से आया है वह >बन जाता है ^

एक BackFlip प्रोग्राम समाप्त हो जाता है जब IP सीमा से बाहर चला जाता है, यानी ग्रिड बंद हो जाता है। यह सभी बैकफ्लिप कार्यक्रमों को समाप्त करता है, क्योंकि अंत में अनंत लूप असंभव हैं। (आप मान सकते हैं कि यह सच है।)

इस चुनौती में आपका लक्ष्य एक प्रोग्राम या फ़ंक्शन लिखना है जो BackFlip प्रोग्राम में होता है और प्रोग्राम को समाप्त करने से पहले निर्देश सूचक द्वारा ले जाने वाली चालों की संख्या को आउटपुट करता है। यही है, प्रोग्राम चलाने के दौरान आईपी कितने कदम उठाता है? इसमें ग्रिड पर प्रारंभिक चरण और अंतिम चरण शामिल हैं।

उदाहरण के लिए, निर्देश सूचक तुच्छ ग्रिड में 5 चरण लेता है ....:

 ....  <- empty 4×1 grid
012345 <- step number of the IP

तो करने के लिए उत्पादन ....है 5

अधिक जटिल 4 × 2 ग्रिड में

\...
\.><

आईपी ​​अपने 9 वें चरण पर ग्रिड से बाहर निकलता है, इसलिए आउटपुट है 9:

step  grid  IP position (@)
0     \...  @....
      \.><   ....

1     \...   @...
      \.><   ....

2     /...   ....
      \.><   @...

3     /...   ....
      /.><   .@..

4     /...   ....
      /.><   ..@.

5     /...   ....
      /.<<   ...@

6     /...   ....
      /.<<   ..@.

7     /...   ....
      /.><   .@..

8     /...   ....
      /.><   @...

9     /...   ....
      \.><   ....
             @

बाइट्स में सबसे छोटा कोड जीतता है।

यदि आप चाहें तो मल्टीलाइन स्ट्रिंग के बजाय वर्णों की एक पंक्ति या मैट्रिक्स के रूप में इनपुट ले सकते हैं, लेकिन आपको वर्णों का उपयोग करना चाहिए ./\<>^V(पूर्णांक opcodes नहीं)। यदि आप .पसंद करते हैं तो आप इसके स्थान का उपयोग कर सकते हैं । यह ठीक है अगर \इनपुट में बच जाने वाले पात्रों की तरह है। आउटपुट हमेशा एक से अधिक पूर्णांक होता है।

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

....
5

\...
\.><
9

.
2

..
3

.
.
2

\
2

^
2

.^.
3

<.
2

\\
\/
7

>V
^<
6

>\
>/
6

\><
2

\><
\><
7

\><
\><
\><
12

\.V.
\.\<
5

\.V.
\./<
9

V./\
V./\
>./<
..\/
14

\V..
.^..
\/><
.V..
.^..
20

\.V.V.
\./.\<
.>\<..
..^.^.
31

\.V.V.V.
\./>/.\<
.>\>\<..
..^.^.^.
69

\.V.V.V.V.
\./>/>/.\<
.>\>\>\<..
..^.^.^.^.
145

\.V.V.V.V.V.V.V.V.V.V.
\./>/>/>/>/>/>/>/>/.\<
.>\>\>\>\>\>\>\>\>\<..
..^.^.^.^.^.^.^.^.^.^.
9721

1
यह ऐसी शर्म की बात है कि आप इसके लिए BackFlip समाधान नहीं कर सकते ...
HyperNeutrino

दर्पणों के बारे में उलझन में है ... करता है / दिशाओं को बाएं => ऊपर और ऊपर => बाएं ,?
अधिकारिक

1
@officialaimm बाईं ओर /से जाने से IP ऊपर जाएगा और ऊपर /जाने से IP सही जाएगी, जैसे कि यह एक दीवार से उछलती हुई गेंद हो। (लेकिन /आईपी ​​को छूने के बाद बैकस्लैश में बदलाव याद रखें ।)
केल्विन के

6 के बजाय '\\' <LF> '\' क्यों 7 है?
tsh

जवाबों:


3

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

f=(a,x=0,y=0,d=3)=>a[x]&&(c=a[x][y])?(a[x][y]=c=='.'?c:c=='/'?(d^=3,'\\'):c=='\\'?(d^=1,'/'):'v>^<'[d][d='^<v>'.search(c),0],f(a,d<3?x+d-1:x,d?y+d-2:y,d)+1):1

स्वतंत्र रूप से @ tsh के उत्तर से विकसित हुआ, हालांकि हड़ताली समान।

^<v>0-3 से पूर्णांक तक दिशाओं की मैपिंग इस तथ्य से नियंत्रित होती है कि .search('^')0 से रिटर्न होता है क्योंकि ^एक रेग्जेक मेटाचैकर है।


मुझे लगता है कि बहुत पीटा गया। मैं वहाँ अंत में काफी उलझन में था जब तक मुझे एहसास नहीं हुआ कि मैं क्या उम्मीद कर रहा था की तुलना में x और y फ़्लिप हो गए थे।
अर्जन जोहान्सन

@ ;RjanJohansen यह एक अच्छी बात है; शायद मुझे हर जगह y के साथ x स्वैप करना चाहिए ताकि समझने में आसानी हो।
नील

2

हास्केल , 333 325 बाइट्स

संपादित करें:

  • -8 बाइट्स: fपॉइंटफ्री और मर्ज किए गए b

bStringएस की सूची लेता है और रिटर्न करता है Integer

data C a=C{c::a->(a,C a)}
b g=[0,0]#([0,1],map(maybe(C$m 1)C.(`lookup`zip"./^>V<"[n,m(-1),a[-1,0],a[0,1],a[1,0],a[0,-1]]))<$>g)
[y,x]#(d,g)|g&y||g!!0&x=1|n@([f,e],_)<-(($d).c)?x?y$g=1+[y+f,x+e]#n
l&i=i<0||i>=length l
(f?i)l|(p,a:r)<-splitAt i l=(p++).(:r)<$>f a
n d=(d,C n)
a v d=(v,C$a$(0-)<$>d)
m s[d,e]=([s*e,s*d],C$m(-s))

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

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

  • C aएक डेटा प्रकार का उपयोग किया जाता है क्योंकि हास्केल एक प्रकार को स्पष्ट रूप से घोषित किए बिना पुनरावर्ती होने की अनुमति नहीं देगा। Cएक रैपिंग कंस्ट्रक्टर भी है और cइसका संबंधित अलिखित फ़ंक्शन है। यह केवल के साथ प्रयोग किया जाता हैa=[Int]
    • प्रकार C [Int]एक सेल कमांड का प्रतिनिधित्व करता है, एक फ़ंक्शन के रूप में जो एक दिशा ( [Int]) तर्क लेता है , और एक नई दिशा, और एक नया C [Int]मान देता है।
  • bमुख्य कार्य है। यह प्रत्येक चरित्र को एक Cमूल्य में परिवर्तित करता है , फिर यह कॉल करता है #
    • g तार तार की एक सूची के रूप में है।
    • चूंकि \बच निकलने की जरूरत है और इसलिए उल्लेख करने के लिए सबसे लंबा चरित्र है, इसलिए इसके परिणाम का उपयोग सूची देखने के लिए डिफ़ॉल्ट मान के रूप में किया जाता है।
  • #मुख्य सिमुलेशन चलाता है, के साथ सीमा की जाँच &और नए ग्रिड के साथ पैदा करता है ?[y,x]वर्तमान स्थिति, dवर्तमान दिशा और gवर्तमान ग्रिड है। [f,e]अगली दिशा है, और nयह और अगले ग्रिड की एक जोड़ी है।
  • l&iजाँच करता है कि सूची के लिए सूचकांक iसीमा से बाहर है या नहीं l। (यह Trueसीमा से बाहर की ओर लौटता है , क्योंकि इसमें एक डमी गार्ड की स्थिति से बचा जाता है #।)
  • कब f(l!!i)==(d,x), वें तत्व के साथ सूची (f?i)l==(d,m)कहां mसे बदल दी गई । lix
    • तकनीकी रूप (?i)से एक अधिक सामान्य लेंस है, जो किसी सूची के i'th तत्व पर ध्यान केंद्रित करता है, इस मामले में (,) [Int]फंक्शनल उदाहरण के साथ उपयोग किया जाता है ।
  • n एक डॉट का प्रतिनिधित्व करने वाला कार्य है।
  • a v एक दिशा में तीर का प्रतिनिधित्व करने वाला एक कार्य है v
  • m sएक दर्पण का प्रतिनिधित्व करने वाला एक कार्य है; s==1के लिए \\और के s==-1लिए /

1

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

f=(a,d=3,x=0,y=0,n=1)=>(p=a[y]||[],q=p[x])?(p[x]=~(t='^<V>'.indexOf(q))?'^<V>'[d^2]:q=='/'?(t=3-d,'\\'):q=='\\'?(t=d^1,'/'):(t=d,q),f(a,t,x+(t&1&&t-2),y+(~t&1&&t-1),n+1)):n

लेकिन मैं आखिरी टेस्टकेस का परीक्षण नहीं कर सकता क्योंकि मैं अपनी मशीन पर ढेर हो गया। (बड़ा राम के साथ एक मशीन है, तो काम करना चाहिए)

हम दिशा के लिए एक नंबर का उपयोग करते हैं:

  • 0: ^
  • 1: <
  • 2: वी
  • 3:>

आज्ञा दें dसंख्या ...

  • अगर हम एक '/' से मिलते हैं, तो हमें d = 3 - d की आवश्यकता है;
  • अगर हम एक '\' से मिलते हैं तो हमें d = d ^ 1 चाहिए;
  • अगर हम '^ <V>' से मिलते हैं, तो हमें d = '^ <V>' चाहिए। indexOf (नोट)

आज्ञा देना (x, y)वर्तमान स्थिति हो, अगले स्थिति है: x+(t&1&&t-2),y+(~t&1&&t-1)

ध्यान दें:

फ़ंक्शन निम्न प्रारूप के साथ एक पैरामीटर लेता है:

[ [ '\\', '.', 'V', '.', 'V', '.', 'V', '.', 'V', '.' ],
  [ '\\', '.', '/', '>', '/', '>', '/', '.', '\\', '<' ],
  [ '.', '>', '\\', '>', '\\', '>', '\\', '<', '.', '.' ],
  [ '.', '.', '^', '.', '^', '.', '^', '.', '^', '.' ] ]

इसका परीक्षण यहां करें

f=(a,d=3,x=0,y=0,n=1)=>(p=a[y]||[],q=p[x])?(p[x]=~(t='^<V>'.indexOf(q))?'^<V>'[d^2]:q=='/'?(t=3-d,'\\'):q=='\\'?(t=d^1,'/'):(t=d,q),f(a,t,x+(t&1&&t-2),y+(~t&1&&t-1),n+1)):n

    ;k=x=>x.split('\n').map(t=>t.split(''));
<textarea id=v>\.V.V.V.V.
\./>/>/.\<
.>\>\>\<..
..^.^.^.^.</textarea><br/><button onclick="r.textContent=f(k(v.value))">Solve</button>
<p>Result: <output id=r></output></p>


बस दस्तावेज़ करने के लिए, मैं Uncaught RangeError: Maximum call stack size exceeded16 जीबी रैम के साथ मिल रहा हूं ।
ज़ेब मैककॉर्ले

1
@ZebMcCorkle अहा, बस पता करें कि "सख्त का उपयोग करें" और कुछ varघोषणाएं इसे अंतिम टेस्टकेस पास करती हैं (जेएस दुभाषिया करते हैं टेल कॉल ऑप्टिमाइज़िंग सख्त मोड में)
tsh

1

सी, 232 221 बाइट्स

d,n,t,m[4]={1,-1};char*w="><^V/\\.",*P;main(o,v)char**v;{for(P=v[1],m[2]=-(m[3]=strchr(P,10)-P+1);P>=v[1]&&P<strchr(v[1],0)&&*P^10;++n)*P=w[((o=d,t=strchr(w,*P)-w)<4)?d=t,o^1:(t<6)?d^=t-2,9-t:6],P+=m[d];printf("%d",n+1);}

पहले तर्क में इनपुट लेता है, परिणाम प्रिंट करता है। यह आवश्यक है कि इनपुट में कम से कम 1 न्यूलाइन हो (इसलिए यदि केवल 1 पंक्ति है, तो उसे एक नई पंक्ति के साथ समाप्त होना चाहिए)

उदाहरण का उपयोग:

./backflip '....
';

टूट - फूट:

d,                                          // Direction
n,                                          // Step counter
t,
m[4]={1,-1};                                // Movement offsets
char*w="><^V/\\.",                          // Command lookup
*P;                                         // Cursor location
main(o,v)char**v;{
    for(P=v[1],                             // Begin at 0,0
        m[2]=-(m[3]=strchr(P,10)-P+1);      // Find width of grid
        P>=v[1]&&P<strchr(v[1],0)&&*P^10;   // While inside grid:
        ++n)                                //  Increment step
        *P=w[                               //  Update the current cell
            ((o=d,t=strchr(w,*P)-w)         //  (store current direction & command)
              <4)?d=t,o^1:                  //   If <>^V, write backflip & set dir
            (t<6)?d^=t-2,9-t:               //   If / or \, write flip & bounce
            6],                             //   If ., write unchanged & continue
        P+=m[d];                            //  Move
    printf("%d",n+1);                       // Print result
}

1

पायथन 3 , 286 बाइट्स

[f () इनपुट के रूप में लेता है {(0,0):'/',(0,1):'.'}इसलिए मैंने उस फॉर्म में लाइनों की एक सरणी परिवर्तित करने के लिए एक फ़ंक्शन जी () भी लिखा है]

def f(r):
 x=y=0;d='>';s=1
 while 1:
  try:c=r[y,x];m='>^<V'.find(d)
  except:break
  if(c=="\\"):d='V<^>'[m];r[y,x]="/"
  elif(c=="/"):d='^>V<'[m];r[y,x]="\\"
  elif(c!="."):r[y,x]='<V>^'[m];d=c
  x+=1if(d=='>')else-1if(d=='<')else 0;y+=1if(d=='V')else-1if(d=='^')else 0;s+=1
 return s

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

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