একটি স্নেক পার্সার তৈরি করুন!


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
ইনপুটটিতে কি একটি একক স্ট্রিং থাকতে হবে বা আমরা একটি স্ট্রিং নিতে পারি []? ইনপুটটির প্রতিটি লাইন কি একই দৈর্ঘ্যের প্যাডযুক্ত বা আমাদের অনিয়মিত লাইনের দৈর্ঘ্যের সাথে মোকাবেলা করতে হবে?
CAD97

2
এটি আমাকে একটি রুবিস কিউব প্রশ্নে পিঁপড়ের পথে ভয়ঙ্কর ফ্ল্যাশ ব্যাক দিচ্ছে।
ম্যাট

প্রারম্ভিক বিভাগটি সর্বদা 0 0, চরের 0 লাইনে থাকবে বা আমাদের এটি খুঁজে পেতে হবে?
মেয়রমন্টি

1
@ স্পিডিনিজা পরীক্ষার কেস 2 এবং 4 উভয়ই (0,0) এ শুরু হয় না এবং পরীক্ষার কেস 0 (সাপের মতো দেখায়) শুরু হয় না বা শেষ হয় না (0,0)।
CAD97

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 এর জন্য আরও ভাল: ডি)

সমস্ত স্পেস, নাম ইত্যাদি স্ট্রিপ করুন তারপর আমি +1 করব। এটি সঠিকভাবে গল্ফ না হওয়া পর্যন্ত আমি ভোট দিচ্ছি না।
mbomb007

2
অথবা, দুটি কোড স্নিপেট রয়েছে, একটি সম্পূর্ণ গল্ফযুক্ত সংস্করণ, একটি কাজের পঠনযোগ্য উদাহরণ।
মিস্টার পাবলিক

@ mbomb007 আমি লজিক গল্ফিং শেষ করেছি তাই সঠিকভাবে গল্ফ করা সংস্করণ এখানে!
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{...}) নির্দেশ করে poin যদি আশেপাশের কোনও প্রতিবেশী না পাওয়া যায় তবে এটি ধরে নেওয়া হয় যে অবশ্যই একটি ক্রস-ওভার হয়েছে এবং এটি এক ( until nএবং c+=1) না পাওয়া পর্যন্ত এক পর্যায়ে এক পর্যায়ে পৌঁছেছে । এই প্রক্রিয়াটি শরীরের বিভাগগুলির সংখ্যা (মাথা সহ নয়) এর পুনরাবৃত্তি করে .scan(/\w/){...}

আমি ধাঁধাতে যুক্ত টেস্ট কেসটি আমাকে আরও ট্রিপ করে চলেছি, তাই আমি 182 চর হয়ে 218 এ রূপ নিয়েছি Those অতিরিক্ত অক্ষরগুলিই নিশ্চিত করেছিল যে আমার অনুভূমিক পদক্ষেপগুলি পরবর্তী / পূর্ববর্তী লাইনে যাবে না। আমি যদি আরও ভালভাবে এটি মোকাবেলা করতে পারি তবে আমি ভাবছি।

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
}

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