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


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.