Tạo mê cung 5x5x5 đa cấp chỉ với một giải pháp


11

Mục đích của thử thách này là tạo ra mã ngắn nhất (tính theo ký tự) thực hiện thành công các thao tác sau:

Thông số kỹ thuật :

  • Phải tạo một 5x5x5 labyrinthchính xác 1 possible solution(không hơn, không kém)
  • Mê cung phải được tạo ra randomly Nó phải có khả năng tạo mọi giải pháp hiện có nếu còn hoạt động trong nhiều năm
  • Các startfinishphải được đặt trong*opposite corners
  • Bản đồ outputphải ở một trong các định dạng sau:

Tùy chọn đầu ra định dạng 1 strings, printed or alerted :

xxxxx,xxxxx,xxxxx,xxxxx,xxxxx/
xxxxx,xxxxx,xxxxx,xxxxx,xxxxx/
xxxxx,xxxxx,xxxxx,xxxxx,xxxxx/
xxxxx,xxxxx,xxxxx,xxxxx,xxxxx/
xxxxx,xxxxx,xxxxx,xxxxx,xxxxx

Tùy chọn đầu ra định dạng 2 arrays :

[[xxxxx,xxxxx,xxxxx,xxxxx,xxxxx],
[xxxxx,xxxxx,xxxxx,xxxxx,xxxxx],
[xxxxx,xxxxx,xxxxx,xxxxx,xxxxx],
[xxxxx,xxxxx,xxxxx,xxxxx,xxxxx],
[xxxxx,xxxxx,xxxxx,xxxxx,xxxxx]]

Ghi chú đầu ra:

  • Sử dụng 0cho empty1chosquares

  • Đường phá vỡ là không cần thiết

  • Bạn quyết định cái gì indexlà cái gì, nhưng chỉ cần đảm bảo giải thích


* Đây là một ví dụ về những gì tôi muốn nói ở góc đối diện:

nhập mô tả hình ảnh ở đây

Làm rõ :

  • KHÔNG thể di chuyển vàodiagonal
  • KHÔNG thể vượt qua hai lần trên cùng một con đường
  • inaccessible areasđược phép
  • Bạn có thể go up/downnhiều cấp độ liên tiếp

Lời khuyên:

  • Đừng xem chúng như những bức tường, thay vào đó hãy xem chúng như một 5x5x5chồng hình vuông mà một số trong số chúng bị thiếu và bạn có thể đi qua những cái bị thiếu

Nếu có gì đó không rõ ràng, chỉ cần hỏi tôi :)
ajax333221

3
Tuy nhiên, có một chi tiết tôi muốn làm rõ: các bức tường được đặt giữa các hình vuông, hay một bức tường có lấp đầy cả một hình vuông không?
Ilmari Karonen

1
bạn nói 5x5 (một mảng 2D) ở một vài nơi, nhưng các mẫu mã và hình ảnh gợi ý 5x5x5 (một mảng 3D). Tôi giả sử mảng 3D là gì?
Kae Verens

1
Làm thế nào quyết định rằng giải pháp là một mê cung hợp lệ? Ý tôi là, đó có phải là số lượng nhánh mà con đường bên phải có không? nó có phải là một cái gì đó để làm với tỷ lệ 1s đến 0 không?
Kae Verens

2
Khi bạn nói "Mê cung phải được tạo ngẫu nhiên", chúng ta nên suy ra những hạn chế nào? Ví dụ, tôi cho rằng bạn không có ý định cho phép, như một cách đọc theo quy tắc hiện tại, một chương trình chọn giữa hai đầu ra được mã hóa cứng một cách ngẫu nhiên.
Peter Taylor

Câu trả lời:


10

C ++ C, khoảng 1000 670 643 395 297 248 ký tự

Đầu ra mẫu:

00111,10011,10111,00110,11000,
11001,01010,00100,11011,10101,
10111,10101,10001,01010,00101,
11001,11110,11100,11110,10101,
11100,10010,11001,10101,00000,

Cách thức hoạt động: Chương trình sử dụng Brownian Motion để tạo ra các giải pháp. Điểm bắt đầu được đặt. Sau đó, một điểm ngẫu nhiên được chọn và liên tục di chuyển ngẫu nhiên cho đến khi nó chạm vào một và chỉ một điểm trên nhánh bắt đầu. Sau đó, điểm được đặt và nếu nó cũng chạm vào điểm cuối, chương trình sẽ thoát và ma trận được hiển thị. Vì không có điểm nào có thể tham gia hai nhánh, nên chỉ có một con đường xuyên qua mê cung. Chương trình sử dụng hàm rand và đối số nguyên dòng lệnh làm hạt giống, do đó , với hàm rand đủ, cuối cùng có thể tạo ra tất cả các mê cung hợp lệ (tuy nhiên thuật toán này sẽ không tạo ra các khu vực không được kết nối, do đó nó sẽ không tạo ra tất cả mê cung có thể ).

Chuyển động Brown đã bị loại bỏ vì hóa ra là không cần thiết và việc loại bỏ nó đơn giản hóa mã đáng kể. Tôi nghĩ rằng nó làm cho mê cung đẹp hơn mặc dù. Tương tự, đối số hạt giống đã bị loại bỏ, vì yêu cầu trình tạo số ngẫu nhiên không trạng thái có ý nghĩa với tôi hơn là hạt giống 128 bit.

Chương trình có thể bị kẹt trong một vòng lặp vô hạn, vì có thể trong các tình huống mà bất kỳ điểm nào được thêm vào các nhánh sẽ tạo ra nhiều đường dẫn. Điều này có thể sửa được, nhưng tôi nghĩ rằng nó hiếm khi không phải là mối quan tâm đối với môn đánh gôn.

#define M m[*p+1][p[1]][p[2]]
#define F(a,b)for(p[a]=5;p[a]--;putchar(b))
#define f for(i=3;i--;p[i]
p[]={4,4,4},h[3],m[7][6][6]={1};
main(i){
    for(M=2;h[1]^1||(M=1)^h[2];){
        f=rand()%5)
            h[i]=0;
        f++)
            p[i]++,
            h[M]++,
            p[i]-=2,
            h[M]++;
    }
    F(0,10)
        F(1,44)
            F(2,48+!M);
}

Tôi đã thêm dòng mới và thụt vào mã được hiển thị để dễ đọc.


Tôi nghĩ rằng bạn đã giành chiến thắng này ;-) không có cách nào tôi có thể thu hẹp của tôi đến nay
Kae Verens

Tôi thực sự rất thích cuộc thi :-) Tôi hơi ngạc nhiên khi chúng tôi vẫn là câu trả lời duy nhất, tôi dự đoán một người chơi golf hoặc tương tự sẽ đánh bại cả hai chúng tôi cho đến bây giờ.
Sir_Lagsalot

Bằng cách nào đó, một con đường đơn giản, không có nhánh hoặc nút quyết định, dường như không đủ điều kiện là một mê cung thực sự. Hãy thử thêm một số con hẻm mù.
DavidC

@David Carraher Thuật toán tạo ra các ngõ cụt và các đường nhánh như trong mẫu. Không cho phép một điểm mới để kết nối hai nhánh đã có sẵn chỉ đơn giản là ngăn chặn nhiều giải pháp hoặc chu kỳ trong mê cung.
Sir_Lagsalot

@Sir_Lagsalot Cảm ơn bạn đã làm rõ
DavidC

5

JavaScript, 874 816 788 686 682 668 637 ký tự

đầu ra mẫu:

00000,10111,10111,01010,11000
01011,01000,01010,01111,00011
00100,11010,00111,10111,11010
01111,10001,01110,01010,01000
00000,11110,00001,10101,10110

cái này hoạt động bằng cách bắt đầu từ điểm [0,0,0] và thêm ngẫu nhiên thêm một 0 nữa bên cạnh 0 bất cứ nơi nào được phép (được phép == 0 mới không nằm cạnh bất kỳ 0 nào khác ngoại trừ người khởi tạo) cho đến khi không còn nữa bổ sung có thể.

nếu có 0 mới bên cạnh điểm thoát (x * y * z == 48) thì chúng tôi sẽ mở lối ra.

chơi gôn

b=[]
I=Math.random
for(i=5;i--;)for(j=5,b[i]=[];j--;)b[i][j]=[1,1,1,1,1]
b[0][0][0]=0
k=[[0,0,0]]
function q(x,y,z){J=b[x]
if(x<0||y<0||z<0||x>4||y>4||z>4||!J[y][z])return 
n=6-!x||b[x-1][y][z]
n-=!y||J[y-1][z]
n-=!z||J[y][z-1]
n-=x==4||b[x+1][y][z]
n-=y==4||J[y+1][z]
n-=z==4||J[y][z+1]
n==1&&v.push([x,y,z])}while(I){F=k.length
B=k[C=0|I(v=[])*F]
x=B[0]
q(x-1,y=B[1],z=B[2])
q(x,y-1,z)
q(x,y,z-1)
q(x+1,y,z)
q(x,y+1,z)
q(x,y,z+1)
if(D=v.length){k.push(A=v[0|I()*D])
b[A[0]][A[1]][A[2]]=0
if(A[0]*A[1]*A[2]==48)b[4][4][4]=I=0}else{for(E=[];F--;)F^C&&E.push(k[F])
k=E}}for(i=25;i--;)b[H=0|i/5][i%5]=b[H][i%5].join('')
alert(b.join("\n"))

nguyên

window.map=[];
for (i=0;i<5;++i) {
  map[i]=[];
  for (j=0;j<5;++j) {
    map[i][j]=[1,1,1,1,1];
  } 
} 
points=[[0,0,0]];
map[0][0][0]=0;
function spaces(x,y,z) {
  var n=6;
  if (x<0 || y<0 || z<0) return 0;
  if (x>4 || y>4 || z>4) return 0;
  if (!map[x][y][z]) return 0;
  if (!x || map[x-1][y][z]) n--;
  if (!y || map[x][y-1][z]) n--;
  if (!z || map[x][y][z-1]) n--;
  if (x==4 || map[x+1][y][z]) n--;
  if (y==4 || map[x][y+1][z]) n--;
  if (z==4 || map[x][y][z+1]) n--;
  return n;
} 
do {
  var index=Math.floor(Math.random()*points.length);
  point=points[index];
  v=[];
  x=point[0];
  y=point[1];
  z=point[2];
  spaces(x-1,y,z)==1 && v.push([x-1,y,z]);
  spaces(x,y-1,z)==1 && v.push([x,y-1,z]);
  spaces(x,y,z-1)==1 && v.push([x,y,z-1]);
  spaces(x+1,y,z)==1 && v.push([x+1,y,z]);
  spaces(x,y+1,z)==1 && v.push([x,y+1,z]);
  spaces(x,y,z+1)==1 && v.push([x,y,z+1]);
  if (v.length) {
    var point=v[Math.floor(Math.random()*v.length)];
    points.push(point);
    map[point[0]][point[1]][point[2]]=0;
    if (point[0]*point[1]*point[2]==48) {
      map[4][4][4]=0;
    } 
  } 
  else {
    var np=[];
    for (var i=0;i<points.length;++i) {
      i!=index && np.push(points[i]); 
    } 
    points=np;
  } 
} while(points.length);
for (i=0;i<5;++i) {
  for (j=0;j<5;++j) {
    map[i][j]=map[i][j].join('');
  } 
  map[i]=map[i].join();
} 
alert(map.join("\n"));

4

Mathicala: True Labyrinth (827 ký tự)

Ban đầu, tôi đã tạo một đường dẫn từ {1,1,1} đến {5,5,5} nhưng vì không thể thực hiện lần lượt sai nào, tôi đã giới thiệu các nhánh hoặc "điểm quyết định" (đỉnh độ> 2) trong đó người ta sẽ cần phải quyết định con đường nào để đi. Kết quả là một mê cung hoặc mê cung thực sự.

"Những con hẻm mù" khó giải quyết hơn nhiều so với việc tìm một con đường trực tiếp đơn giản. Điều khó khăn nhất là loại bỏ các chu trình trong đường dẫn trong khi cho phép các chu trình thoát khỏi đường dẫn giải pháp.

Hai dòng mã sau đây chỉ được sử dụng để hiển thị các biểu đồ được vẽ, do đó mã không được tính, vì nó không được sử dụng trong giải pháp.

o = Sequence[VertexLabels -> "Name", ImagePadding -> 10, GraphHighlightStyle -> "Thick", 
    ImageSize -> 600];

o2 = Sequence[ImagePadding -> 10, GraphHighlightStyle -> "Thick", ImageSize -> 600];

Mã đã được sử dụng:

e[c_] := Cases[EdgeList[GridGraph[ConstantArray[5, 3]]], j_ \[UndirectedEdge] k_ /; (MemberQ[c, j] && MemberQ[c, k])]

m[] :=
Module[{d = 5, v = {1, 125}},
   While[\[Not] MatchQ[FindShortestPath[Graph[e[v]], 1, 125], {1, __, 125}],

v = Join[v, RandomSample[Complement[Range[125], v], 1]]];
   Graph[e[Select[ConnectedComponents[Graph[e[v]]], MemberQ[#, 1] &][[1]]]]]

w[gr_, p_] := EdgeDelete[gr, EdgeList[PathGraph[p]]]

y[p_, u_] := Select[Intersection[#, p] & /@ ConnectedComponents[u], Length[#] > 1 &]

g = HighlightGraph[lab = m[],  PathGraph[s = FindShortestPath[lab, 1, 125]],o]
u = w[g, s]
q = y[s, u]

While[y[s, u] != {}, u =  EdgeDelete[u, Take[FindShortestPath[u,  q[[1, r = RandomInteger[Length@q[[1]] - 2] + 1]], 
  q[[1, r + 1]]], 2] /. {{a_, b_} :> a \[UndirectedEdge] b}];

q = y[s, u]]

g = EdgeAdd[u, EdgeList@PathGraph[s]];

Partition[StringJoin /@ Partition[ReplacePart[Table["x", {125}], 
Transpose[{VertexList[g], Table["o", {Length[VertexList@g]}]}]/. {{a_, b_} :>  a -> b}], {5}], 5]

Sản lượng mẫu

{{"oxooo", "xxooo", "xoxxo", "xoxxo", "xxoox"}, {"ooxoo", "xoooo", "ooxox", "oooxx", "xooxx"}, {"oooxx" "ooxxo", "ooxox", "xoxoo", "xxxoo"}, {"oxxxx", "oooox", "xooox", "xoxxx", "oooxx"}, {"xxxxx", "ooxox", "oooox "," xoxoo "," oooxo "}}

Dưới mui xe

Hình dưới đây cho thấy mê cung hoặc mê cung tương ứng với giải pháp ({{"ooxoo",...}}được hiển thị ở trên:

giải pháp1

Đây là mê cung tương tự được chèn trong 5x5x5 GridGraph. Các đỉnh được đánh số là các nút trên con đường ngắn nhất ra khỏi mê cung. Lưu ý các nhánh hoặc điểm quyết định tại 34, 64 và 114. Tôi sẽ bao gồm mã được sử dụng để hiển thị biểu đồ mặc dù đó không phải là một phần của giải pháp:

HighlightGraph[gg = GridGraph[ConstantArray[5, 3]], g,  
 GraphHighlightStyle ->"DehighlightFade", 
 VertexLabels -> Rule @@@ Transpose[{s, s}] ]

giải pháp2

Và biểu đồ này chỉ hiển thị giải pháp cho mê cung:

HighlightGraph[gg = GridGraph[ConstantArray[5, 3]], 
   Join[s, e[s]], GraphHighlightStyle -> "DehighlightFade", VertexLabels -> Rule @@@    Transpose[{s, s}] ]

giải pháp3

Cuối cùng, một số định nghĩa có thể giúp đọc mã:

các định nghĩa


Giải pháp ban đầu (432 char, Tạo ra một con đường nhưng không phải là một mê cung hay mê cung thực sự)

Hãy tưởng tượng một khối rắn lớn 5x5x5 được tạo thành từ các khối đơn vị riêng biệt. Sau đây bắt đầu mà không có khối đơn vị tại {1,1,1} và {5,5,5}, vì chúng tôi biết chúng phải là một phần của giải pháp. Sau đó, nó loại bỏ các khối ngẫu nhiên cho đến khi có một đường dẫn không bị chặn từ {1,1,1} đến {5,5,5}.

"Mê cung" là con đường ngắn nhất (nếu có thể có nhiều hơn một) với các khối đơn vị đã bị loại bỏ.

d=5
v={1,d^3}
edges[g_,c_]:=Cases[g,j_\[UndirectedEdge] k_/;(MemberQ[c,j]&&MemberQ[c,k])]

g:=Graph[v,edges[EdgeList[GridGraph[ConstantArray[d,d]]],v]];

While[\[Not]FindShortestPath[g,1,d^3]!={},
    v=Join[v,RandomSample[Complement[Range[d^3],v],1]]]

Partition[Partition[ReplacePart[
   Table["x",{d^3}],Transpose[{FindShortestPath[g,1,d^3],Table["o",{Length[s]}]}]
      /.{{a_,b_}:>  a->b}],{d}]/.{a_,b_,c_,d_,e_}:>  StringJoin[a,b,c,d,e],5]

Thí dụ:

{{"ooxxx", "xxxxx", "xxxxx", "xxxxx", "xxxxx"}, 
 {"xoxxx", "xoooo", "xxxxo", "xxxxo", "xxxxo"}, 
 {"xxxxx", "xxxxx", "xxxxx", "xxxxx", "xxxxo"}, 
 {"xxxxx", "xxxxx", "xxxxx", "xxxxx", "xxxxo"}, 
 {"xxxxx", "xxxxx", "xxxxx", "xxxxx", "xxxxo"}}

Về mặt kỹ thuật, đây chưa phải là một mê cung thực sự, vì không có ngã rẽ nào mà người ta có thể thực hiện. Nhưng tôi nghĩ nó thú vị khi bắt đầu vì nó dựa trên lý thuyết đồ thị.

Thói quen thực sự tạo ra một mê cung nhưng tôi đã cắm tất cả các vị trí trống có thể làm phát sinh chu kỳ. Nếu tôi tìm được cách xóa chu kỳ, tôi sẽ đưa mã đó vào đây.


Cập nhật đẹp, tôi thích rằng giải pháp cập nhật của bạn cho phép chu kỳ trên các đường dẫn không phải là giải pháp, nó làm cho một mê cung khó hiểu hơn.
Sir_Lagsalot

Cảm ơn. Thỉnh thoảng tôi vẫn muốn có đường dẫn giải pháp có khả năng xoay chuyển khỏi nút cuối cùng. Điều này hiện không được khuyến khích (nhưng không được ngăn chặn hoàn toàn) bởi FindShortestPath.
DavidC

Tôi không quá quen thuộc với matlab, nhưng bạn có thể làm điều gì đó như FindShortestPath, thêm một thiên vị cho mỗi nút trong đường dẫn ngắn nhất và sau đó chạy FindShortestPath một lần nữa có tính đến độ lệch để nó sẽ tránh các nút trong giải pháp ngắn nhất không? Điều này có thể được thực hiện lặp đi lặp lại quá. Tôi muốn biết loại đường nào sẽ tạo ra.
Sir_Lagsalot

@Sir_Lagsalot Tôi đăng này như một câu hỏi cho các nhóm Mathematica SE đây ( mathematica.stackexchange.com/questions/4084/... )
DavidC
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.