एक साँप पार्सर बनाओ!


14

सांप इस तरह दिखते हैं:

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

सांप खुद को इस मामले में पार कर सकता है:

 @
 ^
>^>v
 ^<<

क्रॉसओवर मान्य होने के लिए, दोनों तरफ के वर्ण समान दिशा में आगे बढ़ रहे होंगे। के मामले में

 @
>^v
 ^<

अस्पष्ट और अमान्य माना जा सकता है।

आउटपुट WASDसिर से पूंछ तक जाने का प्रतिनिधित्व करने वाला एक स्ट्रिंग है ( @)।

एक ऐसे सांप को देखते हुए, जो पीछे नहीं जाता है और अस्पष्ट नहीं है, क्या आप एक ऐसा प्रोग्राम लिख सकते हैं जो साँप द्वारा ले जाने वाली चालों का उत्पादन करेगा?

यह कोड-गोल्फ है, इसलिए सबसे कम उत्तर जीतता है!

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

(नोट: @किसी भी वर्ण के साथ प्रतिस्थापित किया जा सकता है v^<>)

इनपुट:

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

आउटपुट: ddddssaassdddddww


इनपुट:

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

आउटपुट: dddsssaaawww


इनपुट:

>>>v
   v       @
   v       ^
   >>>>v   ^
       >>>>^

आउटपुट: dddsssddddsddddwww


इनपुट:

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

आउटपुट: ssaaaassddwwwwaa


इनपुट:

@v<v
^v^v
^v^<
^<

आउटपुट: ssawwasssawww


1
क्या इनपुट में एक स्ट्रिंग होना चाहिए या हम एक स्ट्रिंग [] ले सकते हैं? क्या इनपुट की प्रत्येक पंक्ति समान लंबाई की होती है या हमें अनियमित रेखा की लंबाई से निपटना पड़ता है?
1897 में CAD97

2
यह मुझे एक rubiks घन प्रश्न पर एक चींटी के पथ के लिए भयानक फ्लैश बैक दे रहा है।
मैट

क्या शुरुआती सेगमेंट हमेशा लाइन 0, चार 0 पर होगा, या हमें इसे ढूंढना होगा?
मेयरमोनी

1
@SpeedyNinja परीक्षण के मामले 2 और 4 दोनों शुरू नहीं हुए हैं (0,0), और परीक्षण के मामले 0 (सांप दिखते हैं) शुरू नहीं होते हैं (0,0) पर समाप्त होते हैं।
सीएडी 97

1
@ CAD97 ओह, यह बहुत ही
कठिन है

जवाबों:


7

जावा, 626 539 536 529 बाइट्स

-87 बाइट्स में बहुत सारी जगहों पर बचत करके। कुछ बाहर इशारा करने के लिए धन्यवाद मिस्टर पब्लिक को जाता है।

-3 बाइट्स क्योंकि मैं पहली बार कोशिश करने वाले सभी स्थानों को हटाने का प्रबंधन नहीं कर सकता (धन्यवाद mbomb007)

इस मामले को ठीक करने के लिए +8 बाइट्स:

@v<v
^v^v
^v^<
^<

-15 बाइट्स फ्रंट-लोडिंग वेरिएबल डिक्लेरेशन द्वारा

s->{String o="",t;String[]p=s.split("\n");int h=p.length,w=p[0].length(),y=0,x,b=0,a,n,m;char[][]d=new char[h][w];for(;y<h;y++)for(x=0;x<w;x++){d[y][x]=p[y].charAt(x);if(d[y][x]=='@')d[y][x]=' ';}for(;b<h;b++)for(a=0;a<w;a++){t="";x=a;y=b;n=0;m=0;while(!(y<0|y>h|x<0|x>w||d[y][x]==' ')){if(y+m>=0&y+m<h&x+n>=0&x+n<w&&d[y+m][x+n]==d[y-m][x-n])d[y][x]=d[y-m][x-n];n=m=0;switch(d[y][x]){case'^':t+="W";m--;break;case'<':t+="A";n--;break;case'v':t+="S";m++;break;case'>':t+="D";n++;}x+=n;y+=m;}o=t.length()>o.length()?t:o;}return o;}

पठनीय संस्करण:

static Function<String,String> parser = snake -> {
    // declare all variables in one place to minimize declaration overhead
    String output = "", path;
    String[] split = snake.split("\n");
    int h=split.length, w=split[0].length(), y=0, x, startY=0, startX, dx, dy;
    char[][] board = new char[h][w];
    // setup char[][] board
    for (; y<h; y++)
        for (x=0; x<w; x++) {
            board[y][x]=split[y].charAt(x);
            if(board[y][x]=='@')board[y][x]=' ';
        }
    // find the longest possible path
    for (; startY<h; startY++)
        for (startX=0; startX<w; startX++) {
            path = "";
            x=startX; y=startY; dx=0; dy=0;
            while (!(y<0 | y>h | x<0 | x>w || board[y][x] == ' ')) {
                if (y + dy >= 0 & y + dy < h & x + dx >= 0 & x + dx < w
                        && board[y + dy][x + dx] == board[y - dy][x - dx]) {
                    board[y][x] = board[y - dy][x - dx];
                } dx = dy = 0;
                switch(board[y][x]) {
                    case '^':path+="W";dy--;break;
                    case '<':path+="A";dx--;break;
                    case 'v':path+="S";dy++;break;
                    case '>':path+="D";dx++;break;
                }
                x+=dx; y+=dy;
            }
            output = path.length()>output.length()?path:output;
        }
    return output;
};

एक स्ट्रिंग की तरह लेता है v @\n>>>^। प्रत्येक समन्वय पर शुरू होने वाला मार्ग बनाता है, फिर सबसे लंबे समय तक वापसी करता है। अतिव्यापी रास्तों के लिए आवश्यक लाहहेड सबसे कठिन हिस्सा था।


2
मैं बहुत प्रभावित हूँ। मैं किसी को भी यह प्रयास करने की उम्मीद नहीं थी । और तुम पहले वाले हो। +1। (2016 बाइट्स ठीक है, और 2016 के लिए और भी बेहतर है: D)

सभी रिक्त स्थान, नाम, आदि को तब मैं +1 करूँगा। मैं तब तक वोट नहीं कर रहा हूं जब तक कि यह ठीक से गोल्फ न हो।
mbomb007

2
या, दो कोड स्निपेट हैं, एक पूरी तरह से गोल्फ संस्करण में से एक, काम करने योग्य पठनीय उदाहरण में से एक।
मिस्टर पब्लिक

@ mbomb007 मैंने तर्क गोल्फिंग को पूरा किया ताकि यहाँ ठीक से गोल्फ संस्करण उपलब्ध हो सके!
2197 पर CAD97

2
@ CAD97 इस चुनौती के लिए, मैं कहूंगा कि यह जावा में एक उत्कृष्ट गोल्फ है।
मिस्टर पब्लिक

1

रूबी, 217

->a{r=''
z=a.index ?@
a.tr!('<^>v',b='awds').scan(/\w/){c=0
e,n=[a[z,c+=1][?\n]?p: c,d=c*a[/.*
/].size,a[z-c,c][?\n]?p: -c,-d].zip(b.chars).reject{|i,k|!i||a[v=i+z]!=k||0>v}.max_by{|q|q&[a[z]]}until n
z+=e
r=n*c+r}
r}

यह शुरू होता है @और पीछे की ओर चलता है, पड़ोसियों की तलाश में जो वर्तमान स्थिति ( z) की ओर इशारा करते हैं । 4-वे चौराहों पर सही तरीके से चुनने के लिए, यह एक ही दिशा ( max_by{...}) में इंगित पड़ोसियों का पक्षधर है । यदि कोई तत्काल पड़ोसी नहीं पाया जाता है, तो यह मानता है कि एक क्रॉस-ओवर रहा होगा और एक समय में एक स्तर तक पहुंच जाता है जब तक कि वह एक ( until nऔर c+=1) नहीं पाता । यह प्रक्रिया शरीर के खंडों की संख्या के लिए दोहराती है (सिर सहित नहीं) ( .scan(/\w/){...})।

परीक्षण के मामले में, मैंने पहेली को जोड़कर मुझे ट्रिपिंग करते हुए रखा, इसलिए मैं 182 चार से 218 तक चला गया। उन अतिरिक्त पात्रों को सभी सुनिश्चित कर रहे थे कि मेरे क्षैतिज कदम अगली / प्रचलित लाइनों में नहीं गए। मुझे आश्चर्य है कि अगर मैं इससे बेहतर तरीके से निपट सकता हूं।

Ungolfed:

f=->a{
  result=''
  position=a.index ?@ # start at the @
  a.tr!('<^>v',b='awds') # translate arrows to letters
  a.scan(/\w/){           # for each letter found...
    search_distance=0
    until distance
      search_distance+=1
      neighbors = [
        a[position,search_distance][?\n]?p: search_distance,  # look right by search_distance unless there's a newline
        width=search_distance*a[/.*\n/].size,   # look down (+width)
        a[position-search_distance,search_distance][?\n]?p: -search_distance, # look left unless there's a newline
        -width                  # look up (-width)
      ]
      distance,letter = neighbors.zip(b.chars).reject{ |distance, letter_to_find|
        !distance || # eliminate nulls
         a[new_position=distance+position]!=letter_to_find || # only look for the letter that "points" at me
         0>new_position # and make sure we're not going into negative indices
       }.max_by{ |q| 
        # if there are two valid neighbors, we're at a 4-way intersection
        # this will make sure we prefer the neighbor who points in the same 
        # direction we're pointing in.  E.g., when position is in the middle of 
        # the below, the non-rejected array includes both the top and left.
        #   v
        #  >>>
        #   v
        # We want to prefer left.
        q & [a[position]] 
        # ['>',x] & ['>'] == ['>']
        # ['v',x] & ['>'] == []
        # ['>'] > [], so we select '>'.
       }
    end
    position+=distance
    result=(letter*search_distance)+result # prepend result
  }
  result # if anyone has a better way of returning result, I'm all ears
}

आपको अपने तर्क को कुछ हद तक सरल बनाने में सक्षम होना चाहिए क्योंकि आपके जोड़े गए मामले को इच्छित दायरे से बाहर माना गया है।
1997 में CAD97
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.