1 ডি হ্যাপিং অ্যারে ম্যাজে


17

অনুপ্রাণিত দ্বারা আমরা মিনার প্লব না এবং এর সাথে সম্পর্কিত 2D কিংকত্র্তব্যবিমূঢ় বিয়োগ 1D

ভূমিকা

আপনার কাজটি নির্দিষ্ট বিধি অনুসরণ করে একটি অ্যারে ধাঁধা থেকে বেরিয়ে আসার জন্য সবচেয়ে সংক্ষিপ্ত পথটি সন্ধান করা।

চ্যালেঞ্জ

একজন 1D অ্যারে একটি সঙ্গে এন উপাদানের গঠিত একটি ধাঁধা হিসেবে গণ্য করা যেতে পারে এন পয়েন্ট, যেখানে সূচকের সাথে বিন্দু সঙ্গে পয়েন্ট সাথে সংযুক্ত করা হয় + + একটি [ ] এবং - একটি [ একটি একমুখী পদ্ধতিতে]। অন্য কথায়, আপনি এগিয়ে অথবা পিছিয়ে ঠিক তিড়িং লাফ পারেন একটি [ সূচকের সাথে বিন্দু থেকে] টি পদক্ষেপ । অ্যারের সীমানার বাইরে সূচকযুক্ত পয়েন্টগুলি গোলকধাঁধির বাইরে বিবেচনা করা হয়।

এটি চিত্রিত করার জন্য, নিম্নলিখিত অ্যারেটি বিবেচনা করুন,

[0,8,5,9,4,1,1,1,2,1,2]

যদি আমরা এখনই 5 ম উপাদানটিতে আছি, যেহেতু উপাদানটি 4, আমরা 9 ​​ম উপাদানটির 4 ধাপ এগিয়ে বা 1 ম উপাদানটির পিছনে 4 ধাপ এগিয়ে যেতে পারি। যদি আমরা পরবর্তীটি করি, আমরা 0 এলিমেন্টটি দিয়ে শেষ করি যা নির্দেশ করে যে আর কোনও চলন সম্ভব নয়। যদি আমরা প্রাক্তনটি করি, যেহেতু নবম এলিমেন্টটি 2, আমরা 11 তম উপাদানটির প্রত্যাশা বেছে নিতে পারি, যা আবার একটি 2, এবং তারপরে আমরা "13 তম উপাদান" এর কাছে আবারও আশা করতে পারি, যা সীমার বাইরে নয় is অ্যারে এবং ধাঁধা থেকে বেরিয়ে আসা বিবেচনা করে।

সুতরাং আমরা যদি উপাদানটি মাঝখানে থেকে শুরু করি, তবে ধাঁধা থেকে বেরিয়ে আসার এক উপায়টি হ'ল 1 ধাপ পিছনে, 4 ধাপ এগিয়ে, 2 ধাপ এগিয়ে এবং 2 ধাপ এগিয়ে, যা অ্যারে হিসাবে প্রকাশ করা যেতে পারে [-1,4,2,2]। বিকল্পভাবে আপনি অ্যারে দিয়ে প্রকাশ করতে পারেন [4,8,10,12]যা সমস্ত মধ্যবর্তী এবং চূড়ান্ত পয়েন্টগুলির শূন্য-ভিত্তিক সূচকটি রেকর্ড করে (1-ভিত্তিক সূচকটিও সূক্ষ্ম), বা কেবল লক্ষণগুলি [-1,1,1,1],।

নিম্ন-সূচকের শেষ থেকে ধাঁধাটি ত্যাগ করাও ঠিক।

প্রথম স্বরলিপিটি ব্যবহার করা এবং একই উপাদান থেকে শুরু [1,1,1,2,2]করাও এটি একটি সমাধান তবে 4 এর পরিবর্তে 5 টি পদক্ষেপ রয়েছে বলে এটি অনুকূল নয়।

কাজটি হল অ্যারে ধাঁধা থেকে বেরিয়ে আসার জন্য সবচেয়ে সংক্ষিপ্ত পথটি খুঁজে বের করা এবং পাথটি আউটপুট। যদি একাধিক অনুকূল পাথ থাকে তবে আপনি যে কোনও বা সমস্তগুলি আউটপুট করতে পারেন। যদি কোনও সমাধান না হয়, আপনার নিজের দ্বারা নির্বাচিত একটি মিথ্যা মানটি আউটপুট করা উচিত যা বৈধ পথ থেকে বিবেচনাযোগ্য (কোনও আউটপুট উত্পাদন করাও ঠিক নয়)।

সরলতার জন্য অ্যারের উপাদানগুলির সংখ্যা সর্বদা একটি বিজোড় সংখ্যা এবং আমরা মাঝেমধ্যে উপাদান থেকে শুরু করি।

পরীক্ষার মামলা

পরীক্ষার কেসগুলি আউটপুট বিভিন্ন ধরণের চিত্রিত করে, তবে আপনি এগুলিতে সীমাবদ্ধ নন।

Input
Output

[0,8,5,9,4,1,1,1,2,1,2]
[-1,4,2,2]

[2,3,7,1,2,0,2,8,9]
[2,9] (or [2,-5] or [[2,9],[2,-5]])

[0,1,2,2,3,4,4,4,3,2,2,3,0]
[1,-1,1,1]

[0,1,2,2,4,4,6,6,6,6,6,4,2,1,2,2,0]
[]

চশমা

  • আপনি কোনও ফাংশন বা একটি সম্পূর্ণ প্রোগ্রাম লিখতে পারেন।

  • অ্যারেতে কেবল নন-নেগেটিভ পূর্ণসংখ্যা থাকে।

  • আপনি যে কোনও স্ট্যান্ডার্ড ফর্মের মাধ্যমে ইনপুট এবং আউটপুট নিতে পারেন , তবে দয়া করে আপনার উত্তরটি নির্দিষ্ট করুন যে আপনি কোন ফর্মটি ব্যবহার করছেন।

  • এটি , সর্বনিম্ন সংখ্যা বাইট জিতেছে।

  • যথারীতি এখানে ডিফল্ট লুফোলগুলি প্রয়োগ হয়।


উত্তরটি অনন্য থাকলেও কী নেস্টেড অ্যারে আউটপুট করা ভাল? (যেমন [0,8,5,9,4,1,1,1,2,1,2], আউটপুটউটিং [[-1,4,2,2]])
বুদ্বুদ

@ বুবলার হ্যাঁ, আপনি নেস্টেড অ্যারে আউটপুট করতে পারেন।
ওয়েজুন চাউ

বিপরীত ক্রমে পালানোর পথটি ফিরে আসা কি ঠিক? এর [1,1,1,-1]বদলে [-1,1,1,1]?
টন হসপেল

@ টনহসপেল হ্যাঁ, কেবল আপনার উত্তরে এটি বলুন।
ওয়েইজুন চিউ

পরীক্ষার কেস 2 ভুল বলে মনে হচ্ছে, আপনি কি এটি ব্যাখ্যা করতে পারবেন?
edc65

উত্তর:


3

জাভাস্ক্রিপ্ট (ES6), 117 বাইট

0-সূচিযুক্ত মধ্যবর্তী এবং চূড়ান্ত পয়েন্টগুলির একটি অ্যারে বা কোনও সমাধান না থাকলে একটি শূন্য অ্যারে প্রদান করে।

a=>(g=(x,p,d=a[x])=>1/d?[d,-d].map(d=>p.includes(X=x+d)||g(X,[...p,X])):o=o==''|o[p.length]?p:o)(a.length>>1,o=[])&&o

এটি অনলাইন চেষ্টা করুন!

মন্তব্য

a =>                              // given the maze a[]
  (g = (                          // g = recursive function taking:
    x,                            //   x = current position
    p,                            //   p[] = list of visited cells
    d = a[x]                      //   d = value of current cell
  ) =>                            //
    1 / d ?                       // if d is defined:
      [d, -d].map(d =>            //   for d and -d:
        p.includes(X = x + d) ||  //     if the cell at X = x + d was not yet visited,
        g(X, [...p, X])           //     do a recursive call to g() at this position
      )                           //   end of map()
    :                             // else:
      o =                         //   update o:
        o == '' |                 //     if o was empty
        o[p.length] ?             //     or p is shorter than o:
          p                       //       set o to p
        :                         //     else:
          o                       //       let o unchanged
  )(a.length >> 1, o = [])        // initial call to g(), starting in the middle
  && o                            // return o

3

তুষ , 22 বাইট

ḟȯ¬€ŀ¹FS+o*!¹⌈½L¹ṁπṡ1ŀ

লক্ষণগুলির তালিকা বা কোনও সমাধানের অস্তিত্ব না থাকলে একটি খালি তালিকা প্রদান করে। এটি অনলাইন চেষ্টা করুন!

ব্যাখ্যা

এটি একটি নিষ্ঠুর-শক্তি সমাধান যা -1,0,1ক্রমবর্ধমান দৈর্ঘ্যের উপরে তালিকাগুলি পরীক্ষা করে এবং প্রথমটি দেয় যা অ্যারে থেকে ঝাঁপিয়ে দেয়। যেহেতু এটি ন্যূনতম দৈর্ঘ্যের, এটিতে 0 টি থাকবে না।

ḟȯ¬€ŀ¹FS+o*!¹⌈½L¹ṁπṡ1ŀ  Implicit input, say A = [0,1,1]
                     ŀ  Indices of A: [1,2,3]
                 ṁ      Map over them and concatenate:
                  π      Cartesian power
                   ṡ1    of the symmetric range [-1,0,1].
                        Result is B = [[-1],[0],[1],[-1,-1],...,[1,1,1]]
ḟ                       Find the first element of B that satisfies this:
                         Argument is a list, say C = [1,-1].
      F                  Reduce C from the left
             ⌈½L¹        using ceil(length(A)/2) as the initial value
       S+o*!¹            with this function:
                          Arguments are an index of A, say I = 2, and a sign, say S = 1.
           !¹             The element of A at I: 1
         o*               Multiply by S: 1
       S+                 Add to I: 2
                         At the end of the reduction, we have a number I, here 2.
   €ŀ¹                   Is it an element of the indices of A: Yes.
 ȯ¬                      Negate: No.
                        The result is the shortest list C for which I is outside of A.

2

পাইথন 3 , 195 188 179 বাইট

def f(a):
 v=len(a);x,*s={v//2},[v//2]
 while all(v>b>-1for*c,b in s)*s:s=[x.add(u)or c+[b,u]for*c,b in s for u in[b+a[b],b-a[b]]if{u}-x]
 return[b[1:]for b in s if not-1<b[-1]<v]

এটি অনলাইন চেষ্টা করুন!

সম্পাদনা:

  • 9 টি বাইট দ্বারা সংরক্ষিত all(..)and s => all(..)*s, if u not in x => if{u}-x
    পূর্বের শোষণগুলি boolean * list == int * list, পরবর্তীগুলি সেট পার্থক্য ব্যবহার করে (খালি সেটটিও মিথ্যা)।

আউটপুট ফর্ম্যাট: মধ্যবর্তী এবং চূড়ান্ত পয়েন্টগুলির শূন্য-ভিত্তিক সূচক হিসাবে দেওয়া সমস্ত অনুকূল উত্তরের নেস্টেড অ্যারে।

উদাহরণস্বরূপ: f([0,8,5,9,4,1,1,1,2,1,2]) == [[4, 8, 10, 12]]

অ্যালগরিদম সহজ বিএফএস। ইতিমধ্যে পরিদর্শন করা সূচকগুলি বাদ দিয়ে, পুনরাবৃত্তিতে sসমস্ত সম্ভাব্য iদৈর্ঘ্যের পাথ রেকর্ড করে i। নোট করুন যে বর্ধিত তারা চিহ্নিতকরণ (আব) ব্যবহৃত হয়েছে কারণ বারবার অ্যারে অ্যাক্সেস ব্যয়বহুল। আমি দেখতে পেয়েছি যে এই জাতীয় স্বরলিপিটি সঠিকভাবে ব্যবহার করা হলে কিছু শ্বেতস্থানও হ্রাস করতে পারে।

আমি উপরের সমাধানটির বাইরে একটি পুনরাবৃত্ত (তবে দীর্ঘ) সংস্করণও তৈরি করেছিলাম। উভয় s andএবংor s প্রয়োজনীয়, অন্যথায় এটি কাজ করে না।

পাইথন 3 , 210 বাইট

lambda a:[b[1:]for b in g(a,[[len(a)//2]],{len(a)//2})if not-1<b[-1]<len(a)]
g=lambda a,s,x:s and all(-1<b<len(a)for*c,b in s)and g(a,[x.add(u)or c+[b,u]for*c,b in s for u in[b+a[b],b-a[b]]if u not in x],x)or s

এটি অনলাইন চেষ্টা করুন!


2

হাস্কেল , 207 202 বাইট

5 টি বাইট সংরক্ষণ করেছে বিএমওকে ধন্যবাদ ।

l=length
x!p|i<-h p,d<-x!!i=[p++[x]|x<-[(-d,i-d),(d,i+d)],x`notElem`p]
x?p|i<-h p=i<0||i>=l x
h=snd.last
x#[]=[]
x#p|l(x%p)<1=x#(p>>=(x!))|1>0=x%p
(%)=filter.(?)
f x=(tail.map fst)<$>x#[[(0,l x`div`2)]]

এটি অনলাইন চেষ্টা করুন!

এটি একটি ফাংশন যা একটি তালিকা গ্রহণ করে Int প্যারামিটার হিসাবে এবং সেই পাথের একটি তালিকা ফেরত দেয় যেখানে প্রতিটি পাথ অ্যারে থেকে বেরিয়ে আসার জন্য আপেক্ষিক জাম্পগুলির একটি তালিকা।

অবারিত সংস্করণ:

move :: [Int] -> [(Int, Int)] -> [Path]
move xs path = map(\x->path++[x]) $ filter (\s -> s`notElem`path) $ [(-delta, i-delta), (delta, i+delta)]
  where (_,i) = last path
        delta = xs!!i :: Int

outside :: [Int] -> Path -> Bool
outside xs paths = i < 0 || i >= length xs
  where (_,i) = last paths

shortest' :: [Path] -> [Int] -> [Path]
shortest' paths xs | null paths       = []
                   | not (null ready) = ready
                   | otherwise        = shortest' paths' xs
                   where ready  = filter (outside xs) paths
                         paths' = concatMap (move xs) paths

shortest xs = map tail $ map (map fst) $ shortest' [[(0,length xs`div`2)]] xs

2

সি (জিসিসি) , 269 বাইট

#define A n){for(printf("%d,",n);i^l[i];i=l[i])printf("%d,",x[i]);break;}if(!u[n]){u[n]=x[m]=n;l[m++]=i;
#define M calloc(r,sizeof(s))
*x,*u,*l,s,m=1,i,j,n,w;main(r,v)char**v;{s=r-1;x=M;u=M;l=M;for(*x=1+s/2;i<m;i++){j=x[i];if(w=atoi(v[j])){n=j+w;if(s<A}n=j-w;if(1>A}}}}

এটি অনলাইন চেষ্টা করুন!

প্রাথমিকভাবে পুনরাবৃত্ত ব্যাকট্র্যাকিং অনুসন্ধানের চেষ্টা করেছিলাম, কারণ mainপুনরাবৃত্তির জন্য ব্যবহার করা সবসময়ই মজাদার। শেষ পর্যন্ত যদিও একটি সরল অপরিবর্তনীয় প্রস্থের প্রথম সন্ধানটি আরও ছোট করা সম্ভব হয়েছিল, যা এই সংস্করণটি। এই প্রোগ্রামটি ইনপুট অ্যারেটি কমান্ড-লাইন আর্গুমেন্ট হিসাবে গ্রহণ করে, কোনও ধনুর্বন্ধনী ছাড়াই, যেমন 0 8 5 9 4 1 1 1 2 1 2প্রথম সরবরাহিত উদাহরণ হিসাবে। স্টেটআউটে প্রোগ্রাম আউটপুটগুলিতে বিবৃতিগুলির একটি তালিকা অনেকগুলি অক্ষর নেয়। উপরের প্রথম পরীক্ষার উদাহরণের সাথে সম্পর্কিত আউটপুট উদাহরণস্বরূপ। 1-সূচিযুক্ত বিপরীত ক্রমে , কমা-বিস্মৃত অ্যারে সূচকগুলির করে, চূড়ান্ত থেকে শুরু করে, বাইরে-বাইরে / 'পালিয়ে যায়' সূচক এবং মধ্যবর্তী সূচকের মধ্য দিয়ে ফিরে কাজ করে (এটি আউটপুট দেয় না কেন্দ্র, সূচনা সূচনা)। প্রোগ্রামটি অ্যারের চারপাশে ব্রেসগুলি আউটপুট দেয় না এবং পৃথক হওয়ার কারণে একটি পেছনের কমা ছেড়ে দেয়printf13,11,9,5,

অ্যারে ধাঁধা থেকে যদি কোনও পালানোর পথ না থাকে তবে প্রোগ্রামটি কোনও কিছুই আউটপুট দেয় না।

ডিগল্ফড এবং ব্যাখ্যা করেছেন এটি নীচে রয়েছে (পঠনযোগ্যতার জন্য কিছু পরিবর্তন সহ ভারীভাবে ডলফোর্ড করা হয়েছে):

int *x, *u, *l, s, m = 1, i, j, n, w;                        //Declare all the state we'll need
int main(r, v) char** v;{                            
    s = r - 1;                                               //s is our actual array size, since v[0] is the program name.
    x = calloc(r, sizeof(int));                              //x is an array that will form our BFS queue. Since it is a BFS we've no need to visit any elements more than once (first visit will have been on a shortest route to it), so the amount of space we have here should suffice.
    u = calloc(r, sizeof(int));                              //u is an array that will be used to flag when an array index has been visited; only reason it's int* is for ease of declaration
    l = calloc(r, sizeof(int));                              //l is an array that will be used parallel to x and stores backpointers in the form of indexes into x, which will be used to construct the actual path once it is found.
    x[0] = 1 + (s/2);                                        //Init the first element in the queue to our center index of the array, adding one because of the program name in v/argv.
    for(; i < m; i++) {                                      //m is the number of elements in our BFS queue. It starts at 1 and grows during iteration; if this loop terminates before finding a path there is none.
        j = x[i];                                            //Current index in the array we are examining
        if (w = atoi(v[j])) {                                //Set w to be the actual array value at the current index (and check that it's nonzero since if it isn't we can't get anywhere from here)
            n = j + w;                                       //Try a move in the positive direction
            if (n > s) {                                     //If the move escapes the array
                for(printf("%d,", n); i ^ l[i]; i = l[i]) {  //Print the location escaped to and then loop back through the backpointers to reconstruct the path. The only backpointer that will point to its own queue index is the starting one, so terminate there.
                    printf("%d,", x[i]);                     //Print each intermediate array index
                }
                break;                                       //Then break the outer for loop and exit.
            }
            if(!u[n]) {                                      //If the jump didn't take us out of the array and we haven't visited where it goes to, add it to the queue.
                u[n] = x[m] = n;                             //m is the current tail of the queue, so put this new location there. Since we're 1-indexed and if n was zero we'd have escaped, we know it isn't so can use it to mark this index as visited also.
                l[m++] = i;                                  //Also set the backpointer for this new queue element to point back to the current index, then increment the tail of the queue.
            }
            n = j - w;                                       //Now the backwards move
            if (n < 1) {                                     //Repeat analogous to the forward case.
                for(printf("%d,", n); i ^ l[i]; i = l[i]) {
                    printf("%d,", x[i]);
                }
                break;
            }
            if (!u[n]) {
                u[n] = x[m] = n;
                l[m++] = i;
            }
        }
    }
}

গল্ফড সি কোডের জন্য যথারীতি, সংকলন আউটপুটটিতে অবশ্যই সতর্কতা এবং নোটগুলির একটি বন্ধুত্বপূর্ণ প্রাচীর অন্তর্ভুক্ত থাকবে।



1

পার্ল 5 , -এ: 73 বাইট

(পুরানো শৈলী কাউন্টিং: 75 বাইট, +1জন্য aএবং +1প্রতিস্থাপন জন্য -//দ্বারা -/$/এবং ব্যবহার $`জন্য $')

#!/usr/bin/perl -a
use 5.10.0;
@;=$#F/2;$v{$^H=$_}//=push@;,map$'+$_*($F[$^H]//1/!say$').$".$',-//,1for@

STDIN এ এক লাইনের হিসাবে ইনপুট অ্যারে দিন 0 8 5 9 4 1 1 1 2 1 2

প্রারম্ভিক পয়েন্ট সহ বিপরীত ক্রমে ভিজিট করা অবস্থানগুলি মুদ্রণ করে, তারপরে ক্র্যাশ হয়

সমাধান না হলে কিছুই মুদ্রণ করে না

এটি অনলাইন চেষ্টা করুন!


1

রুবি , ১০২ বাইট

->a{b=[[a.size>>1]];b.map{|x|(v=a[w=x[0]])&&w>=0?[w-v,w+v].map{|j|x.index(j)?0:b<<[j]+x}:(break p x)}}

এটি অনলাইন চেষ্টা করুন!

প্রস্থান থেকে প্রারম্ভিক বিন্দুতে (অন্তর্ভুক্ত) প্রান্তরে পালিয়ে যাওয়ার পথটি মুদ্রণ করে আউটপুটকে অ্যারে হিসাবে ইনপুট ধাঁধাটি নেয়। কোনও প্রস্থান না হলে কিছুই প্রিন্ট করে না।

এই পদ্ধতির পথের ইতিহাস সংরক্ষণ করে অস্থায়ী অ্যারে দিয়ে পুনরাবৃত্তি করতে মানচিত্রের পদ্ধতিটি অপব্যবহার করে, যা যখনই অন্য কোনও সম্ভাব্য পদক্ষেপ নিতে হয় তখনই উড়তে ক্রমাগত প্রসারিত হয়।

নীতিগতভাবে, আমি return xপরিবর্তে ব্যবহার করে অন্য একটি বাইট সংরক্ষণ করতে পারি break p x, তবে এর অর্থ এই হবে যে আমার মিথ্যা মানটি এই সমস্ত রাক্ষুশ জঞ্জালের মধ্যে সমান b। সম্ভবত, এটি আউটপুটের অনুমোদিত নমনীয়তা বিবেচনা করেও অনেক বেশি হবে ...

walkthrough

->a{
  b=[[a.size>>1]] #Initialize an array of paths with our starting point index
  b.map{|x|       #Iterate through this array
    (v=a[w=x[0]]) #w is the current point in the path, v is its array value
    &&w>=0        #Ruby's support for negative indexing costs us 6 bytes :(
    ?             #If we are still within the bounds of the maze
      [w-v,w+v].map{|j| #Try moving in both directions
        x.index(j)? #If we have been there before, or stuck on zero
        0         #This is a dead-end, just assign a throwaway value
        :b<<[j]+x #Otherwise push the elongated path on top of our iterator
      } 
    :(break p x)  #Escaped! Exit the loop and report the path
  }  
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.