একটি বিপরীত তীর ধাঁধা সমাধান করুন


14

এটি একটি "তীর ধাঁধা":

  v      < 
>     v    
      >  ^ 
>         v
^ <       *

*চিহ্ন স্পট যেখানে আপনি শেষ হবে। আপনার লক্ষ্যটি হ'ল ধাঁধাটি কোথায় শুরু হয় (অতএব, বিপরীত গোলকধাঁধা) to এই ক্ষেত্রে, এটি প্রথম> দ্বিতীয় লাইনে ।

  v------< 
S-+---v  | 
  |   >--^ 
>-+-------v
^ <       *

নোট করুন যে সমস্ত তীর অবশ্যই ব্যবহার করা উচিত। এছাড়াও নোট করুন যে আপনি ধরে নিতে পারেন যে লাইনগুলি সমান দৈর্ঘ্যের ফাঁক দিয়ে প্যাড করা হবে।

আপনার প্রোগ্রামটি অবশ্যই কোনও যুক্তিসঙ্গত উপায়ে গোলকধাঁটিকে ইনপুট করতে হবে (স্ট্যান্ডিন, কোনও ফাইল, বার্তা বাক্স, ইত্যাদি থেকে), তবে গোলকধাঁধা অবশ্যই সম্পূর্ণ অক্ষত। উদাহরণস্বরূপ, আপনি কমা দ্বারা পৃথক করা লাইনগুলি ইনপুট করতে পারবেন না; ইনপুটটি অবশ্যই গোলকধাঁধা হতে হবে।

আপনাকে অবশ্যই কোনও যুক্তিযুক্ত উপায়ে গোলকধাঁটির শুরুতে আউটপুট করতে হবে। উদাহরণস্বরূপ, আপনি পারে

  • শুরুতে স্থানাঙ্ক আউটপুট
  • আউটপুট শুরুর তীর দিয়ে পুরো ধাঁধাটি একটি দ্বারা প্রতিস্থাপিত S
  • শুরু তীর সরিয়ে বাদে সমস্ত তীর দিয়ে পুরো ধাঁধা আউটপুট আউট (হোয়াইট স্পেস অক্ষত!)
  • প্রভৃতি

যতক্ষণ আপনি আপনার আউটপুট দ্বারা বলতে পারবেন কোন তীরটি শুরুর তীর, তা ঠিক আছে। উদাহরণস্বরূপ, এর একটি আউটপুট

"0"
"2"

ঠিক আছে, নতুন লাইন এবং উক্তি নির্বিশেষে, কারণ আপনি এখনও বলতে পারেন যে শুরুটি কোথায় ছিল।

এটি , তাই বাইটের মধ্যে সংক্ষিপ্ততম কোডটি জিতবে।


এটা অনুমান করা কি যুক্তিযুক্ত যে প্রতিটি তীরটিতে কেবল একটি অন্য তীর এটি দেখিয়েছে? এমন এক উদাহরণ হতে যাচ্ছে না যেখানে একাধিক সূচনা পয়েন্টগুলি থাকতে পারে?
ড্যানি

একে অপরের তীরটি একবার থেকে একবার দেখার জন্য কী "ধাঁধাঁ সূচনা" হয়? অন্য কথায় ড্যানির প্রশ্ন + অনুমান কোনও লুপ নেই।
shiona

3
"আপনি কমা দ্বারা আলাদা করা লাইনগুলি ইনপুট করতে পারবেন না; ইনপুটটি অবশ্যই গোলকধাঁধা হতে হবে।" এটি একটি অপ্রয়োজনীয় সীমাবদ্ধতা মত মনে হয় যেহেতু "ঠিক ধাঁধা" আগে থেকেই কার্যত বিভাজিত সারি মধ্যে নতুন লাইন দিয়ে। কেন একজনের উপর অন্য একটি সীমানাকে অগ্রাধিকার দেবেন?
জোনাথন ভ্যান মাত্রে

1
@ ডুরকনবব এটি যুক্তিসঙ্গত, যেহেতু কেউ তাত্ত্বিকভাবে "ডিলিটারগুলি" তে একটি সম্পূর্ণ সংকোচিত সমাধানকে এনকোড করতে পারে। তবে আমি সন্দেহ করি যে এই বিধিনিষেধটি নির্দিষ্ট ভাষার বিরুদ্ধে একটি নির্দিষ্ট ভাষাগত পক্ষপাতের পরিচয় দেয়। যদি নিয়মটি ছিল "ইনপুট সারিগুলি আপনার পছন্দের কোনও একটি চরিত্রের দ্বারা সীমিত করা যেতে পারে All সমস্ত সারি অবশ্যই একই চরিত্রের দ্বারা সীমিত করতে হবে ?" আমি মনে করি উপরের সীমাটি দরকারী কারণ এটি এমন একটি ডোমেন প্রতিষ্ঠা করে যার মধ্যে আপনার প্রোগ্রামটি অবশ্যই কাজ করবে।
জোনাথন ভ্যান

1
যে শুধু মানে যে, উদাহরণস্বরূপ, মধ্যে @Peter প্রতি নির্দেশ করা হয় , না । আমি যখন আজ একটি কম্পিউটারে বাড়ি ফিরব তখন আমি আরও স্টাফ সম্পাদনা করব। >v^>v^
ডুরকনব

উত্তর:


4

গল্ফস্ক্রিপ্ট, 55 বাইট

:&,,{&=42>},.{.&="><^v"?[1-1&n?~.~)]=:d;{d+.&=32=}do}%-

অনলাইন ডেমো

ধরে নেওয়া যায় যে সমস্ত ইনপুট লাইন একই দৈর্ঘ্যে ফাঁক দিয়ে নিউলাইন দ্বারা পৃথক করা হয়েছে। ইনপুট স্ট্রিংয়ের সূচনা থেকে প্রারম্ভিক তীরের বেট অফসেট আউটপুট দেয় (উদাহরণস্বরূপ 12চ্যালেঞ্জের ধাঁধাটির উদাহরণ)।

বিশেষতঃ, এই প্রোগ্রামটি সমস্ত তীরগুলির বাইট অফসেটগুলি খুঁজে পেয়েছে যা অন্য কোনও তীর তাদেরকে নির্দেশ করছে না (ধরে নিই যে সমস্ত তীর একটি তীর বা লক্ষ্যকে নির্দেশ করে; এটি সত্য না হলে অদ্ভুত আচরণ ঘটতে পারে)। ডিফল্টরূপে, যদি এখানে বেশ কয়েকটি তীর থাকে (যা প্রতি অনুমান অনুযায়ী, বৈধ ইনপুটটিতে সম্ভব না হওয়া উচিত) তবে তাদের অফসেটগুলি আউটপুটে কেবল সংশ্লেষিত হবে। আপনি যদি চান n*তবে পরিবর্তে নতুন লাইনের মাধ্যমে তাদের আলাদা করার জন্য আপনি প্রোগ্রামটিতে যুক্ত করতে পারেন।

মন্তব্য সহ ডি গল্ফ সংস্করণ:

:&                     # save a copy of the input string in the variable "&"
,, { &= 42> },         # make a list of the byte offsets of all arrows 
.                      # duplicate the list and apply the following loop to it:
{
  .                    # make a copy of the original offset...
  &=                   # ...and get the corresponding character in the input
  "><^v" ?             # map the arrow character to integers 0 to 3, and...
  [ 1 -1 &n?~ .~) ]=   # ...map these to +1, -1, -len-1 or +len+1, where len is the...
  :d;                  # ...length of the first input line, and save result as "d"
  { d+ . &= 32= } do   # add d to the byte offset until another non-space is found
} %
-                      # subtract the resulting list of target offsets from the
                       # original list of arrow offsets; this should leave exactly
                       # one offset, which is left on the stack for output

1
আপনি যদি ইনলাইন করেন তবে আপনি 3 টি অক্ষর সংরক্ষণ করতে পারেন w
হাওয়ার্ড

@ হাওয়ার্ড: হু, তাই আমি পারি। ধন্যবাদ! অতিরিক্ত জায়গার প্রয়োজন এড়াতে নামকরণ zকরতে &হয়েছিল, যদিও। OTOH, ?~.~)একটি সুন্দর সুন্দর হাসি তোলে। :-)
ইলমারি করোনেন

5

গল্ফস্ক্রিপ্ট ( 101 ১০ বাইট)

n/:g,,{:&g=:r,,{&1$r='^v<>*'?70429 3base 2/=++}/}%{,4=},.{2<}%:&\{2/~\{[~2$~@+(@@+(\]&1$?)!}do\;}%^`

আউটপুট সেই ফর্মটিতে রয়েছে [[x y]]যেখানে সমন্বয়গুলি উভয়ই 0-ভিত্তিক।

অনলাইন ডেমো

প্রক্রিয়াজাতকরণ দুটি পর্যায়ে রয়েছে: প্রথম পর্যায়ে [x y dx dy]গোলকধাঁটিকে টিপলসের অ্যারে রূপান্তরিত করে ; দ্বিতীয় পর্যায়ে প্রতিটি তীর / নক্ষত্রটি তীর / নক্ষত্রের দিকে এটি নির্দেশ করে maps (তারকাচিহ্নগুলি তাদের দিকে ইঙ্গিত করার জন্য বিবেচনা করা হয়)। সমস্যার সংজ্ঞা অনুসারে ঠিক একটি তীর রয়েছে যা এই মানচিত্রের ফলস্বরূপ নয় এবং এটিই সমাধান।


আপনি এই পোস্ট করার সময় আমি আমার উত্তরটি পাস্ট করছি। আমাদের একই ধারণা ছিল তবে আপনি এটি সফলভাবে গল্ফ করতে পেরেছেন। সুন্দর!
Vereos

@ পিটারটেলর আমি দেখতে পাচ্ছি না যে এটি ক্ষেত্রে সঠিকভাবে বিন্দুটি পরিচালনা করে যা মন্তব্যে উল্লেখ করা হয়েছে।
হাওয়ার্ড

@ হওয়ার্ড, আমি জানি না যে মামলাটি কী। স্পষ্টতা চাইবে।
পিটার টেলর

আপনি দয়া করে আপনার ইনপুট এবং আউটপুট একটি উদাহরণ পোস্ট করবেন?
ডেভিডসি

@ ডেভিডকার্যাহার, অনলাইন ডেমো দেখুন। ;'STUFF'স্টিডিনের STUFFমাধ্যমে সরবরাহের অনুকরণ করে ।
পিটার টেলর

2

গণিত 491 323

মন্তব্যে অসম্পূর্ণ

প্রক্রিয়াটি সমাপ্তি ("*") থেকে শুরু হয়, তীরটি এটি চিহ্নিত করে এবং এটি সূচনা না হওয়া পর্যন্ত এগিয়ে যায়।

ফাংশন, চ [ধাঁধা]।

(* positions of the arrowheads *)
aHeads[a_]:=Position[m,#]&/@{"^","v",">","<"}

(* position of the final labyrinth exit*)
final[a_]:=Position[a,"*"][[1]];


(* find arrowheads that point to the current location at {r,c} *)
aboveMe[{r_,c_},a_]:=Cases[aHeads[a][[2]],{r1_,c}/;r1<r]
belowMe[{r_,c_},a_]:=Cases[aHeads[a][[1]],{r1_,c}/;r1>r]
rightOfMe[{r_,c_},a_]:=Cases[aHeads[a][[4]],{r,c1_}/;c1>c]
leftOfMe[{r_,c_},a_]:=Cases[aHeads[a][[3]],{r,c1_}/;c1<c]

(*find the precursor arrowhead*)
precursor[{loc_,a_,list_:{}}]:=

(* end the search when the precursor has already been traversed or when there is no precursor *)
Which[MemberQ[list,loc],list,
loc=={},list,True,


(* otherwise find the next precursor *)

পূর্ববর্তী

(* return the path through the maze from start to finish *)
f[maze_]:= precursor[{final[maze[[1]]],maze[[1]]}]

Golfed

f@z_:=Module[{p,h,m=z[[1]]},h@a_:=Position[a,#]&/@{"^","v",">","<","*"};
  p[{v_,a_,j_:{}}]:=Module[{r,c,x=Cases},{r,c}=v;
  Which[MemberQ[j,v],j,v=={},j,True,
  p[{Flatten[{x[h[a][[2]],{r1_,c}/;r1<r],x[h[a][[1]],{r1_,c}/;r1>r],
  x[h[a][[4]],{r,c1_}/;c1>c],x[h[a][[3]],{r,c1_}/;c1<c]},2],a,Prepend[j,v]}]]];
  p[{Position[m,"*"][[1]],m}]]

উদাহরণ

গোলক - ধাধা. প্রতিটি অর্ডার করা জোড়ায় একটি ঘরের সারি এবং কলাম থাকে। উদাহরণস্বরূপ {2, 3। সারি 2, কলাম 3 এ সেলটি বোঝায়।

maze=Grid[Normal@ SparseArray[{{5, 5} -> "*",{1, 2} -> "v", {1, 5} -> "<",{2, 1} -> ">",
   {2, 3} -> "v",{3, 3} -> ">", {3, 5} -> "^",{4, 1} -> ">", {4, 5} -> "v",{5, 1} -> "^", 
   {5, 2} -> "<",{_, _} -> " "}]]

ধাঁধা


ইনপুট

f[maze]

আউটপুট : শুরু থেকে শেষের পথ।

{{2, 1}, {2, 3}, {3, 3}, {3, 5}, {1, 5}, {1, 2}, {5, 2}, {5, 1}, { 4, 1}, {4, 5}, {5, 5}


আপনার ইনপুট ফর্ম্যাটটি ভুল - "ইনপুটটি অবশ্যই গোলকধাঁধা হতে হবে"।
ডুরকনব

ইনপুটটি এখন নিজেই ধাঁধা।
ডেভিডসি

আমি কোডটি অনুসরণ করি নি, তবে আপনি যেভাবে "ইনপুটটি এখন ধাঁধা" সমাধান করেছেন সেটি হাস্যকর! +1 ... "এসটিডিআইএন সর্বজনীন" বিশ্বাসীর সংখ্যা অবাক করা।
ডাঃ বেলিসারিয়াস

আমি আনন্দিত যে আপনি ইনপুট সমস্যার সমাধানটি প্রশংসা করেছেন।
ডেভিডসি

1

আমি মনে করি এটি সমাধানের জন্য আমি একটি ভাল উপায় খুঁজে পেয়েছি, তবে আমি এটি গল্ফ করে চুষতে পারি। আমি অনুমান করি এটি ওয়ে সংক্ষিপ্ত হতে পারে, তাই আমি আমার ধারণাটি ব্যাখ্যা করতে যাচ্ছি যাতে অন্যরা যদি এটির ভাল লাগে তবে এটি ব্যবহার করতে পারে।

যদি প্রতিটি তীর ব্যবহার করা আবশ্যক, তবে সমস্ত তীরগুলি অন্য একটি তীর দ্বারা চিহ্নিত করা হবে, একটি বাদে, এটি আমাদের সমাধান।

এর অর্থ হ'ল আমাদের ধাঁধাটি পিছনের দিকে খেলতে হবে না, তবে উপরের-বাম দিক থেকে শুরু করে আমাদের কেবল প্রত্যেকটির জন্য নিকটতম বিন্দুযুক্ত তীরটি পরীক্ষা করা দরকার। বৃহত্তর ম্যাজেসগুলির জন্য এটি একটি বাস্তব পেইনসেভার (যেহেতু আপনাকে চারটি দিকই পরীক্ষা করতে হবে না, তবে কেবল একটি)।

এখানে আমার সমাধান:

পিএইচপি, 622 বাইট

$h=fopen("a.txt","r");$b=0;while(($z=fgets($h))!==false){$l[$b]=str_split($z,1);$b++;}$v=array("^","<","v",">");$s=array();for($i=0;$i<count($l);$i++){for($j=0;$j<count($l[0]);$j++){if(in_array($l[$i][$j],$v)){switch($l[$i][$j]){case"^":$c=$i-1;while($l[$c][$j]==" ")$c--;$s[]=$c.",".$j;break;case"v":$c=$i+1;while($l[$c][$j]==" ")$c++;$s[]=$c.",".$j;break;case"<":$c=$j-1;while($l[$i][$c]==" ")$c--;$s[]=$i.",".$c;break;case">":$c=$j+1;while($l[$i][$c]==" ")$c++;$s[]=$i.",".$c;break;}}}}for($i=0;$i<count($l);$i++){for($j=0;$j<count($l[0]);$j++){if(in_array($l[$i][$j],$v)){if(!in_array($i.",".$j,$s)){echo$i.",".$j;}}}}

Ungolfed:

$h=fopen("a.txt","r");
$b=0;
while(($z=fgets($h))!==false) {
    $l[$b]=str_split($z,1);
    $b++;
}
//Input ends here
$v = array("^","<","v",">");
$s = array();
//Here i check every arrow, and save every pointed one in $s
for($i=0;$i<count($l);$i++){
    for($j=0;$j<count($l[0]);$j++){
        if(in_array($l[$i][$j],$v)){
            switch($l[$i][$j]) {
                case "^":
                    $c=$i-1;
                    while ($l[$c][$j]==" ")
                        $c--;
                    $s[]=$c.",".$j;
                    break;
                case "v":
                    $c=$i+1;
                    while ($l[$c][$j]==" ")
                        $c++;
                    $s[]=$c.",".$j;
                    break;
                case "<":
                    $c=$j-1;
                    while ($l[$i][$c]==" ")
                        $c--;
                    $s[]=$i.",".$c;
                    break;
                case">":
                    $c=$j+1;
                    while ($l[$i][$c]==" ")
                        $c++;
                    $s[]=$i.",".$c;
                    break;
            }
        }
    }
}
//I check if the arrow is in $s. If not, we have a solution.
for($i=0;$i<count($l);$i++){
    for($j=0;$j<count($l[0]);$j++){
        if (in_array($l[$i][$j],$v)){
            if (!in_array($i.",".$j,$s)){
                echo$i.",".$j;
            }
        }
    }
}

1

পিএইচপি - 492 বাইট

$r=split("\n",$m);$h=count($r);foreach($r as &$k)$k=str_split($k);$l=count($r[0]);$e=strpos($m,"*")+1-$h;$a=$x=$e%$l;$b=$y=floor(($e-$x)/$l);do{$c=0;for(;--$a>=0;){if($r[$b][$a]==">"){$x=$a;$c++;}if($r[$b][$a]!=" ")break;}$a=$x;for(;--$b>=0;){if($r[$b][$a]=="v"){$y=$b;$c++;}if($r[$b][$a]!=" ")break;}$b=$y;for(;++$a<$l;){if($r[$b][$a]=="<"){$x=$a;$c++;}if($r[$b][$a]!=" ")break;}$a=$x;for(;++$b<$h;){if($r[$b][$a]=="^"){$y=$b;$c++;}if($r[$b][$a]!=" ")break;}$b=$y;}while($c>0);echo "$x-$y";

এই সমাধানটি ধরে নেয় যে মানচিত্রটি স্থানীয় ভেরিয়েবলে পাওয়া যাবে $m। এর মধ্য দিয়ে যাওয়ার জন্য আমার সবচেয়ে সংক্ষিপ্ত পদ্ধতিটি হল $_GET: $m=$_GET['m'];14 বাইটে। ভেরিয়েবলের মানচিত্র সহ একটি অব্যাহত সংস্করণ পড়ার স্বচ্ছতার জন্য নীচে সরবরাহ করা হয়েছে।

$m=<<<EOT
  v      < 
>     v    
      >  ^ 
>         v
^ <       * 
EOT;

$r=split("\n",$m);
$h=count($r);
foreach($r as &$k)
    $k=str_split($k);
$l=count($r[0]);

$e=strpos($m,"*")+1-$h;

$a=$x=$e%$l;
$b=$y=floor(($e-$x)/$l);
do{
$c=0;
for(;--$a>=0;)
    {
        if($r[$b][$a]==">"){$x=$a;$c++;}
        if($r[$b][$a]!=" ")break;
    }
$a=$x;
for(;--$b>=0;)
    {
        if($r[$b][$a]=="v")
            {
                $y=$b;
                $c++;
            }
        if($r[$b][$a]!=" ")break;

    }
$b=$y;
for(;++$a<$l;)
    {
        if($r[$b][$a]=="<")
            {
                $x=$a;
                $c++;
            }
        if($r[$b][$a]!=" ")break;
    }
$a=$x;
for(;++$b<$h;)
    {
        if($r[$b][$a]=="^")
            {
                $y=$b;
                $c++;
            }
        if($r[$b][$a]!=" ")break;
    }
$b=$y;
}while($c>0);
echo "$x-$y";

1

কে, 281 277 258

{{$[&/x in*:'{{~"*"=x 1}{(s;k . s;k;s:*1_w@&(k ./:w:{{x@&x in y}[(*:'{(x[1]@x 0;x 1)}\[x;(z;y)]);i]}[(h!b,b,a,a:#k:x 2)m;(h!(0 1+;0 -1+;1 0+;-1 0+))m:x 1;x 0])in"*",h:"><v^")}\(x;y;z;x)}[*x;y .*x;y];*x;.z.s[1_x]y]}[i@&~(x ./:i::,/(!#x),/:\:!b::#*x)in" *";x]}

এখানে একটি পূর্ববর্তী, অবারিত সংস্করণ

solve:{[x]
    //j - indices of all possible starting points
    //i - every index
    j::i@&~(x ./:i::,/(!a:#x),/:\:!b:#*x) in " *";

    h::">v<^";

    //d - dictionary mapping each directional character to
    //    increment/decerement it needs to apply to the x/y axis
    d::h!((::;1+);(1+;::);(::;-1+);(-1+;::));

    //e - dictionary mapping each directional character to
    //    the maximum number of moves it should make in a 
    //    given direction
    e::h!b,a,b,a;

    //f - function to produce the indices of each point that is 
    //    passed once we move in a certain direction from a 
    //    certain index
    f::{{x@&x in y}[(last'{(x[0];x[0]@'x 1)}\[x;(y;z)]);i]};

    //g - function that, given a starting and a direction,
    //    moves in that direction until hitting another directional
    //    character. It then moves in the new direction etc. until
    //    it reaches the end point -- *
    g::{[x;y;z]
        {[x]
            q:x 0;m:x 1; k:x 2;
            w:f[e m;d m;q];
            s:*1_w@&(k ./:w)in h,"*";
            m:k . s;
            (s;m;k;s)}\[{~"*"=x 1};(x;y;z;x)]};

    // recursive function that starts at the first possible starting point
    // and plots its way to the end. If all other potential starting points
    // have been touched in this path, then this is the correct starting point.
    // else, recursively call the function with the next possible starting point
    :{$[min "b"$j in last'g[*x;y . *x;y];*x;.z.s[1_x;y]]}[j;x]
  }

x y0 ভিত্তিক সূচকগুলি হিসাবে সূচনা পয়েন্টটি প্রদান করে ।

k)maze
"  v      < "
">     v    "
"      >  ^ "
">         v"
"^ <       *"
k)solve maze
1 0

1

পাইথন 422

with open("m.txt","r") as f:m=f.read().split("\n")
p=[(v.find("*"),p) for p,v in enumerate(m) if "*" in v][0]
g=[]
def f(a):
    x,y=b,c=a
    for p,i in enumerate((lambda x:[l[x] for l in m])(x)):
        if i in "^>v<" and((p<y and i=="v")or(p>y and i=="^")):return b,p
    for p,i in enumerate(m[y]):
        if i in "^>v<" and((p<x and i==">")or(p>x and i=="<")):return p,c
while True:
    z=f(p)
    if z in g:break
    else:g.append(z);p=z
print p

ইনপুট নামক একটি ফাইলে থাকে m.txt। আউটপুটটি (x, y)তবে আপনি শেষ মুদ্রণ বিবৃতিটি এতে পরিবর্তন করলে print gআউটপুটটি তালিকা [(x, y), (x, y), ...]থেকে শুরু করে শুরু পর্যন্ত সমস্ত পদক্ষেপের মতো হবে।

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