অসি-আর্ট অ-ছেদ না করার পথ তৈরি করুন


18

2 পূর্ণসংখ্যা ইনপুট ক্ষেত্র মাপ প্রতিনিধিত্বমূলক, প্রদত্ত xএবং y, আউটপুট ক্ষেত্রের মাধ্যমে একটি পাথ।

উদাহরণস্বরূপ আউটপুট 5, 4:

#    
#    
# ###
### #

পুরো ক্ষেত্রটি 5 বাই 4, এবং ক্ষেত্রটি পেরিয়ে হ্যাশমার্ক দিয়ে তৈরি একটি পথ রয়েছে।

পথটি সর্বদা উপরের বাম কোণে শুরু হওয়া উচিত এবং নীচে ডানদিকে যেতে হবে। প্রোগ্রামটি চালানোর সময় পুরো পথটি এলোমেলোভাবে করা উচিত। প্রতিটি বৈধ পাথ একটি সম্ভাব্য আউটপুট হওয়া উচিত।

পাথের নিয়মগুলি হ'ল:

  • হ্যাশমার্ক দিয়ে তৈরি

  • প্রতিটি হ্যাশ কেবলমাত্র 2 টি অন্যান্য হ্যাশগুলির সাথে সংযুক্ত থাকে (অর্থাত্ পথটি ছেদ করে না বা নিজেই পাশাপাশি চলে না)

নন-হ্যাশ স্পেসগুলি এটিকে অন্য কোনও চরিত্রের সাথে পূরণ করা যেতে পারে তবে এটি অবশ্যই সামঞ্জস্যপূর্ণ হতে হবে (অর্থাত্ সমস্ত স্পেস, সমস্ত পিরিয়ড ইত্যাদি) be

উদাহরণ:

2, 2

##
 #

3, 4

##
 ##
  #
  #

5, 5

#####
    #
    #
    #
    #

6, 5

## ###
 # # #
## # #
# ## #
###  #

7, 9

#######
      #
####  #
#  #  #
#  #  #
#  #  #
#  ####
#
#######

এই ধরণের পথটি একটি স্ব-এড়ানো এলোমেলো হাঁটার সাথে সমান, তবে এটি সত্য সংখ্যার চেয়ে পৃথক হতে পারে না।

পথের ধারাবাহিকতা এবং পাথ স্পর্শ উভয়ই কর্ণবিহীন সংজ্ঞায়িত।


আরবিএক্স.লুয়া আউটপুট ফর্ম্যাটটি বৈধ? ;)
ডিভ্রিচার

এটি কি সঠিক যে যতক্ষণ প্রতিটি বৈধ পথটি বেছে নেওয়ার ইতিবাচক সম্ভাবনা থাকে ততক্ষণ সম্ভাবনা বন্টন স্বেচ্ছাসেবী হয়?
flawr

@ দেবআরিচার হ্যাঁ
রুন 5:58

@ ফ্লোর হ্যাঁ, এটি সঠিক
22

উত্তর:


11

ম্যাটল্যাব, 316 305 300 293 বাইট

function P=f(a,b);z(a,b)=0;P=z;c=@(X)conv2(+X,[0,1,0;1,1,1;0,1,0],'s');B=1;while B;P=z;P(1)=1;for K=1:a*b;S=z;S(a,b)=1;for L=2:a*b;S(~S&c(S)&~P)=L;end;[i,j]=find(S&c(P==K));if i;r=randi(nnz(i));else;break;end;P(i(r),j(r))=K+1;if P(a,b);break;end;end;B=any(any(c(P>0)>3));end;P(P>0)=35;P=[P,'']

ধন্যবাদ @ লুইস মেন্ডো বিভিন্ন পরামর্শ এবং একগুচ্ছ বাইটের জন্য =)

এটি অনলাইন চেষ্টা করুন! (ওয়্যারেন্টি ব্যতীত: নোট করুন যে এটি অ্যাক্টেভে চালানোর জন্য কয়েকটি সামঞ্জস্য প্রয়োজন: প্রথমত আমাকে functionকীওয়ার্ডটি মুছে ফেলা এবং মানগুলি হার্ডকোড করা দরকার ছিল , দ্বিতীয়ত: স্প্ল্যাশগুলি মতলবের মতো সঠিকভাবে মুদ্রিত হয় না Also এছাড়াও আমিও করি নি অক্টাভের কনভ্যুশনাল কমান্ডগুলি পরীক্ষা করুন, যা ভিন্নভাবে কাজ করতে পারে))

ইনপুট জন্য উদাহরণ আউটপুট (7,10)(ইতিমধ্যে বেশ কিছু সময় নিতে পারে):

#         
#         
##        
 ##       
  #   ### 
  #   # ##
  #####  #

ব্যাখ্যা

এটি পছন্দসই 4-সংযোগের সাথে উপরের বাম থেকে নীচে ডানদিকে ক্রমান্বয়ে পাথ তৈরি করে এবং তারপরে আপনার অ্যাডজেন্ট অংশগুলি থাকতে পারে না এমন মানদণ্ড লঙ্ঘনকারী পাথগুলি প্রত্যাখ্যান করতে প্রত্যাখ্যানের নমুনা ব্যবহার করে।

function P=f(a,b);
z(a,b)=0;                                 % a matrix of zeros of the size of th efield
P=z;                                    
c=@(X)conv2(+X,[0,1,0;1,1,1;0,1,0],'s');  % our convolution function, we always convolute with the same 4-neighbourhood kernel
B=1;
while B;                                  % while we reject, we generate paths:
    P=z;
    P(1)=1;                               % P is our path, we place the first seed
    for K=1:a*b;                          % in this loop we generate the all shortest paths (flood fill) from the bottom right, withot crossing the path to see what fiels are reachable from the bottom left
        S=z;
        S(a,b)=1;                         % seed on the bottom left
        for L=2:a*b;
            S(~S&c(S)&~P)=L;              % update flood front
        end;
        [i,j]=find(S&c(P==K));            % find a neighbour of the current end of the path, that is also reachable from the bottom left
        if i;                             % if we found some choose a random one
            r=randi(nnz(i));
        else;
            break;                        % otherwise restart (might not be necessary, but I'm too tired to think about it properly=)
        end;
        P(i(r),j(r))=K+1;                 % update the end of the current path
        if P(a,b);                        % if we finished, stop continuing this path
            break;
        end;
    end;
    B=any(any(c(P>0)>3));                 % check if we actually have a valid path
end;
P(P>0)=35;                                % format the path nicely
P=[P,''];

ওহ এবং সর্বদা হিসাবে:

সংকল্প সাফল্যের মূল চাবিকাঠি।


19

বেফুঞ্জ, 344 বাইট

&v>>>#p_:63p:43g`\!+v>/*53g+\01g:2%2*1-\2/!*63g+\0\:v
 40$ v++!\`g14:p35:\<^2\-1*2%2p10::%4+g00:\g36\g35-1_v
#11^$_83p73v >1+:41g`!#v_$,1+:43g`!#v_@>->2>+00p+141^_
<p1^     vp< ^,g+7g36:<<<<1+55p36:<<<< ^1?0^#7g36g35*
8&p|!++!%9#2g+7g10\*!-g38g10!-g37:g00!!*<>3^
443>:!#v_>>1-::3%1-:53g+00p\3/1-:63g+01p^
^>^>>$#<"#"53g63g7+p41g53g-43g63g-+!#^_

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

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

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

অ্যানিমেশনটি কোনও কোণে নিজেকে আটকে রাখার পথ দেখায়

একবার অ্যালগরিদম মাঠের সীমানার নীচে বাম দিকে সেই পরিণতি ঘুরিয়ে নেওয়ার সিদ্ধান্ত নিলে, এটি মূলত নিজেকে লক্ষ্যহীন বিচরণের জন্য আজীবন নিন্দা করেছে। সেদিক থেকে এটির পিছনে পিছনে ডানদিকে ঘুরতে চেষ্টা করার আগে সেই বেড়া বন্ধ অঞ্চলে প্রতিটি সম্ভাব্য পথ অনুসরণ করতে হবে। এবং এই ক্ষেত্রে সম্ভাব্য পাথের সংখ্যা সহজেই জ্যোতির্বিদ্যায় পরিণত হতে পারে।

নীচের লাইন: যদি মনে হয় যে এটি দীর্ঘ সময় নিচ্ছে, তবে কেবলমাত্র কার্যকর করা বাতিল করা এবং আবার শুরু করা ভাল ধারণা।

ব্যাখ্যা

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

এটি সম্ভাব্য স্থানাঙ্কগুলি সহ স্ট্যাককে জনবহুল করে কাজ করে যা আমরা অনুসরণ করতে পারি। তারপরে আমরা স্ট্যাক থেকে একটি সেট টানছি এবং এটি উপযুক্ত কিনা তা পরীক্ষা করে (অর্থাত্ সীমার মধ্যে এবং কোনও বিদ্যমান পাথের সাথে ওভারল্যাপিং নয়)। একবার আমরা একটি ভাল জায়গা পেয়ে গেলে, আমরা #সেই জায়গার প্লেফিল্ডে একটি লিখি এবং পরে আমাদের ব্যাকট্র্যাকের প্রয়োজন হলে সেই বিবরণগুলি স্ট্যাকটিতে যুক্ত করি।

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

হাইলাইট করা বিভিন্ন উপাদান অংশগুলির সাথে কোডটি দেখতে এমন দেখাচ্ছে:

কার্যকরকরণের পথগুলির সাথে উত্স কোড হাইলাইট করা

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


2
পবিত্র গরু। ব্যাখ্যা?
আর

@ ইস্টারলিআইর্ক অনুদানের জন্য আপনাকে ধন্যবাদ এটা অনেক প্রশংসা করা হয়।
জেমস হোল্ডারেন্স

খুশি এটা দরকারী ছিল!
আর

2

কিউব্যাসিক, 259 বাইট

আমি নিশ্চিত ভালবাসা GOTOএস।

RANDOMIZE TIMER
INPUT w,h
DO
CLS
x=1
y=1
REDIM a(w+3,h+3)
2a(x+1,y+1)=1
LOCATE y,x
?"#"
d=INT(RND*4)
m=1AND d
x=x+m*(d-2)
y=y-d*m+m+d-1
c=a(x,y+1)+a(x+2,y+1)+a(x+1,y)+a(x+1,y+2)=1
IF(x=w)*c*(y=h)GOTO 9
IF(x*y-1)*x*y*c*(x<=w)*(y<=h)GOTO 2
LOOP
9LOCATE y,x
?"#"

বেসিক কৌশল: প্রতিটি পদক্ষেপে, #বর্তমান অবস্থানে একটি মুদ্রণ করুন এবং এলোমেলো পথে চলে যান। a0 এবং 1 এর অ্যারে আমরা কোথায় ছিলাম তা ট্র্যাক করে। যদি পদক্ষেপটি বৈধ হয় এবং GOTO 9লুপ থেকে প্রস্থান করে ফাইনালটি প্রিন্ট করতে আমাদের শেষ পয়েন্টে নিয়ে যায় #। অন্যথায়, যদি এই পদক্ষেপ বৈধ হয়, তবে অন্য পদক্ষেপ নিন। অন্যথায়, স্ক্রিনটি সাফ করুন এবং আবার শুরু করুন (ব্যাকট্র্যাকিং অ্যালগরিদমের কোডিংয়ের চেয়ে অনেক গল্ফিয়ার!)।

কিউবি in৪ এ আমার ল্যাপটপে পরীক্ষিত, এটি সাধারণত 9, 9পাঁচ সেকেন্ড বা তারও কম সময়ের জন্য একটি ফলাফল তৈরি করে । রানগুলি 10, 10তিন থেকে 45 সেকেন্ডের মধ্যে যে কোনও জায়গায় নিয়ে গেছে। তাত্ত্বিকভাবে, সমস্ত আইনী পাথের শূন্য-শঙ্কার সম্ভাবনা থাকে তবে বড় বাঁকযুক্ত পাথের সম্ভাবনা খুব কম। আমি মাঝে মাঝে দু'একটি ছোট বাঁকানো পথ দেখেছি, যদিও:

নমুনা পথ

অনুরোধে বর্ণহীন সংস্করণ এবং / অথবা গভীরতার ব্যাখ্যা উপলব্ধ।


2

আর, 225 বাইট

function(x,y){library(igraph);a=matrix(rep(" ",x*y),c(y,x));g=make_lattice(c(y,x));w=runif(ecount(g));for (i in 1:2){v=shortest_paths(g,1,x*y,weights=w)$vpath[[1]];w[]=1;w[E(g)[v%--%v]]=0;};a[v]="#";cat(rbind(a,"\n"),sep="")}

ব্যাখ্যা:

আমরা একটি নিয়মিত (জালিস) [x * y] প্রান্তগুলিতে এলোমেলো ওজনযুক্ত অনির্দেশিত গ্রাফ তৈরি করি তবে আমরা শুরু থেকে শেষের দিকে সবচেয়ে ছোট পথটি পাই। তবে উত্পন্ন পথটিতে এমন কোষ থাকতে পারে যার দু'বারেরও বেশি নীগ্রোবার রয়েছে:

#
#
####
  ##
  #
  ###

সুতরাং আমাদের দু'বার সংক্ষিপ্ত পথ অ্যালগরিদম প্রয়োগ করা উচিত। দ্বিতীয় বারে আমরা বর্তমান ওজনে 0 এ সেট থাকা বর্তমান সন্ধানী পথে থাকা ব্যতীত 1 টির ওজন নির্ধারণ করেছি;

ফলাফল

#
#
### 
  # 
  #
  ###

Ungolfed:

function(x,y){
    library(igraph);#igraph library should be installed
    a=matrix(rep(" ",x*y),c(y,x));#ASCII representation of the graph
    g=make_lattice(c(y,x));# regular graph
    w=runif(ecount(g));#weights
    for (i in 1:2){
        #find vertices that are in the path
        v=shortest_paths(g,1,x*y,weights=w)$vpath[[1]];
        #set all weights to 1 except those that are in the current found path that set to 0
        w[]=1;
        w[E(g)[v%--%v]]=0;
    }
    a[v]="#";
    cat(rbind(a,"\n"),sep="")
}

1

জাভাস্ক্রিপ্ট (ES7), 333 331 330 329 324 318 312 বাইট

f=
(h,w,c=[...Array(h)].map(_=>Array(w).fill` `),g=a=>{for(z of b=[[[h-1,w-1]]])a.map(([x,y])=>b.every(([[i,j]])=>i-x|j-y)&(z[0][0]-x)**2+(z[0][1]-y)**2<2&&b.push([[x,y],...z]));return b.find(([[x,y]])=>!x&!y)||g([...a,[h,w].map(n=>Math.random()*n|0)])})=>g([]).map(([x,y])=>c[x][y]=`#`)&&c.map(a=>a.join``).join`
`
Height: <input type=number min=1 id=h>Width: <input type=number min=1 id=w><input type=button value="Generate!" onclick=o.textContent=f(+h.value,+w.value)><pre id=o>

সম্প্রসারণ: #প্রস্থের প্রথম প্রস্থের সাহায্যে ক্ষেত্রের মধ্য দিয়ে কোনও পথ না পাওয়া পর্যন্ত এগুলি এলোমেলোভাবে অ্যারেতে স্থাপন করা হবে; প্রথম, এবং সবচেয়ে সংক্ষিপ্ততম, এরূপ পথটি তখন আউটপুট; এটি গ্যারান্টি দেয় যে পথটি নিজেকে ছেদ করে না। নোট করুন যে বিশেষত বৃহত্তর ক্ষেত্রগুলির জন্য কোনও পথ সন্ধানের আগে জেএস ইঞ্জিনের স্ট্যাকটি অতিক্রম করা সম্ভব। Ungolfed:

function r(n) {
    return Math.floor(Math.random() * n);
}
function f(h, w) {
    var a = []; // array of placed #s
    var b; // breadth-first search results
    var c;
    do {
        a.push([r(h), r(w)]); // place a # randomly
        b = [[[h - 1, w - 1]]]; // start from bottom right corner
        for (z of b) // breadth-first search
            for ([x, y] of a) // find possible next steps
                if (!b.some(([[i, j]]) => i == x && j == y))
                    if ((z[0][0] - x) ** 2 + (z[0][1] - y) ** 2 < 2)
                        if (x || y)
                            b.push([[x, y], ...z]); // add to search
                        else if (!c)
                            c = [[x, y], ...z]; // found path
    } while (!c);
    a = [...Array(h)].map(() => Array(w).fill(' '));
    for ([x, y] of c) // convert path to output
        a[x][y] = '#';
    return a.map(b => b.join('')).join('\n');
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.