Mê cung có thể được giải quyết?


20

Câu đố

  • In 0 nếu không thể giải quyết được mê cung n * m
  • In 1 nếu mê cung n * m có thể được giải quyết (bằng 1 hoặc nhiều cách)

(vì vậy tôi không yêu cầu đường dẫn nhưng nếu có thể giải quyết !!!)

Mảng đầu vào (2đ):

[[0,0,0,0,0,0,1],[0,0,0,0,0,1,0],[0,0,0,0,1,0,0],[1,0,0,0,0,0,0]]

XXXXXXXXX
XS     XX
X     X X
X    X  X
XX     FX
XXXXXXXXX

0 = can pass through
1 = can not pass trough
[0][n] is the last block of the first line
[m][0] is the first block of the last line

Quy tắc Vị trí bắt đầu là 0,0 và vị trí kết thúc là n, m Bạn chỉ có thể di chuyển theo chiều ngang và chiều dọc Mã ngắn nhất sẽ thắng


Đầu vào nên là một chuỗi hoặc một mảng?
apsillers

3
Nếu có 1 (tường) tại (n, m) thì mã có trả về 0 không?
trichoplax

3
(Tương tự cho một bức tường tại (0,0)?)
Martin Ender

3
Bạn nói đó là mê cung × m, nhưng việc lập chỉ mục của bạn ngụ ý rằng đó là mê cung (n + 1) × (m + 1).
Nick Matteo

3
Tôi đang mong chờ giải pháp regex =)
flawr

Câu trả lời:


7

CJam, 42 41 39 36 35 byte

Wq3>~_s,{{[{_2$+0<{e<_}*}*]}%z}*sW=

Dựa trên những ý tưởng trong câu trả lời này .

4 byte nhờ Trình tối ưu hóa.

Định dạng đầu vào:

[[0 0 0 0 0 0 1] [0 0 0 0 0 1 0] [0 0 0 0 1 0 0] [1 0 0 0 0 0 0]]

@Optimizer Cảm ơn vì điều đó. Nhưng sau đó tôi đã tìm thấy một cách ngắn hơn ...
jimmy23013

1
q2Wts~_s,{{[{_2$+0<{e<_}*}*]}%z}*sW=- 36. Mặc dù giả định rằng ba ký tự đầu tiên của đầu vào sẽ là[[0
Trình tối ưu hóa

7

APL Dyalog, 27 ký tự

⊃⌽∨.∧⍨⍣≡1≥+/¨|∘.-⍨,(~×⍳∘⍴)⎕

đánh giá đầu vào. APL phân biệt giữa ma trận và vectơ vectơ. Chương trình này giả định rằng đầu vào là một ma trận.

(~×⍳∘⍴)Alà một ngã ba tương đương với (~A) × ⍳⍴A. Cần tránh nhắc đến hai lần hoặc giới thiệu một biến.

⍴Alà hình dạng của A. Đối với ma trận 4 nhân 7, hình dạng là 4 7.

là trình tạo chỉ số. ⍳41 2 3 4. ⍳4 7là các vectơ (1 1)(1 2)...(4 7)được sắp xếp theo ma trận 4 nhân 7.

~Alật các bit của A.

×bằng cách nhân ⍳⍴Avới các bit bị lật, chúng ta bảo toàn tọa độ của tất cả các ô tự do và biến tất cả các bức tường thành 0 0.

,phá hủy ma trận của các cặp tọa độ, tức là tuyến tính hóa nó thành một vectơ. Trong trường hợp này, vectơ sẽ bao gồm các cặp.

∘.-⍨Ahoặc A∘.-Atrừ các yếu tố của Acặp đôi. Lưu ý rằng ở đây các yếu tố của Achính họ là cặp.

| giá trị tuyệt đối

+/¨tổng hợp từng cặp giá trị tuyệt đối. Điều này cho chúng ta khoảng cách lưới giữa mỗi cặp ô trong mê cung, tiết kiệm cho các bức tường.

1≥chúng tôi chỉ quan tâm đến hàng xóm ở khoảng cách không quá 1, điều này cũng không bao gồm các bức tường. Bây giờ chúng ta có một ma trận kề của đồ thị.

∨.∧⍨⍣≡ Floyd - Thuật toán đóng bắc cầu của Warshall

(f⍣n)A(không được sử dụng ở đây) trong đó nmột số nguyên là toán tử công suất. Nó áp dụng fcho A nthời gian : f f ... f A.

(f⍣g)Atrong đó glà một hàm, là toán tử điểm cố định, còn gọi là "giới hạn công suất". Nó giữ trên máy tính series A, f A, f f A, ... cho đến khi ((f⍣i)A) g ((f⍣(i+1))A)trở về đúng đối với một số i. Trong trường hợp này, chúng tôi sử dụng match ( ) là g.

∨.∧⍨Ahoặc A∨.∧Alà một bước trong thuật toán của Floyd. f.glà một khái quát của phép nhân ma trận ( +.×), ở đây chúng tôi sử dụng kết hợp ( ) và phân biệt ( ) thay cho +×.

⊃⌽ Sau khi ⍣≡đã áp dụng bước đủ thời gian và đạt đến trạng thái ổn định, chúng ta phải tìm góc trên bên phải của ma trận để có kết quả, vì vậy chúng ta lật nó ( ) và lấy mục đầu tiên, trên cùng bên trái ( ).

Hình dung các ⍣≡bước của


5

Python, 164 byte

def s(a):
 d=[(0,0)]
 while d:i,j=d.pop();a[i][j]=2;d+=[(x,y)for x,y in[(i-1,j),(i,j-1),(i+1,j),(i,j+1)]if len(a[0])>y>-1<x<len(a)and a[x][y]<1]
 return a[-1][-1]>1

Tôi miễn cưỡng đăng bài này vì thực tế là tôi thường làm thế nào để lấp lũ, chỉ cần đánh golf nhẹ. Nhưng dù sao nó ở đây.


4

Perl, 73 byte

69 byte mã + 4 byte cho -n0E(không chắc các thẻ được tính vào năm 2014 như thế nào, vì vậy tôi đã đếm chúng cho 4 thay vì 2, nhưng nó không quan trọng lắm).

/.*/;s/(^0|A)(.{@{+}})?0/A$2A/s||s/0(.{@{+}})?A/A$1A/s?redo:say/A$/+0

Hãy thử trực tuyến! (và nếu bạn thay thế 1111011dòng bằng 1111111, mê cung sẽ không thể giải quyết được nữa và đầu ra sẽ 0thay vì 1: Hãy thử trực tuyến! )

Giải thích:

Mã này sẽ tìm thấy mọi ô có thể tiếp cận của mê cung (và đánh dấu chúng bằng a A): nếu một ô chạm vào một ô được đánh dấu bằng a A, thì nó có thể truy cập được và chúng ta cũng đánh dấu nó A; và chúng tôi làm điều đó một lần nữa ( redo). Điều đó được thực hiện nhờ hai regex: s/(^0|A)(.{@{+}})?0/A$2A/skiểm tra xem một khoảng trắng ở bên phải hay dưới cùng của a A, trong khi s/0(.{@{+}})?A/A$1A/skiểm tra xem một khoảng trắng ở bên trái hay trên đỉnh của a A. Cuối cùng, nếu ô cuối cùng chứa một ô có Athể truy cập được, nếu không thì không (đó là say/A$/+0kiểm tra; +0đây là để đảm bảo kết quả sẽ 0hoặc 1thay vì chuỗi rỗng1).
Lưu ý rằng /.*/sẽ khớp với toàn bộ một dòng, do đó cài đặt@+đến chỉ mục ở cuối dòng đầu tiên, có kích thước của một dòng, cho phép sử dụng để sử dụng .{@{+}}để khớp chính xác nhiều ký tự như trên một dòng. ( @{+}tương đương với @+, nhưng chỉ cái trước có thể được sử dụng trong regex)


Đối với trường hợp thử nghiệm này , mã của bạn xem xét mê cung có thể giải quyết được ngay cả khi vị trí cuối cùng là 1.
Jitse

@Jitse Bắt tốt. Trên thực tế, đó là do các liên kết TIO không sử dụng đúng mã (tôi đoán đó là một số phiên bản trước đó và tôi đã không phát hiện ra nó). Câu trả lời vẫn còn hiệu lực và tôi đã cập nhật các liên kết TIO. Ví dụ của bạn hoạt động tốt: Hãy thử trực tuyến!
Dada

Ô đung rôi! Cảm ơn đã làm rõ, tôi thích cách tiếp cận này.
Jitse

@ Xin cảm ơn, đó là một trong những sân golf yêu thích của tôi :)
Dada

3

Ruby, 133 130 129 ký tự

a=eval gets
f=->x,y{a[x][y]=1
[[-1,0],[1,0],[0,-1],[0,1]].map{|o|d,e=x+o[0],y+o[1]
f[d,e]if a[d]&&a[d][e]==0}}
f[0,0]
p a[-1][-1]

Đầu vào trên STDIN, đầu ra 1hoặc 0trên STDOUT.

Khó chịu dài. Nó chỉ đơn giản là lấp đầy lũ 1từ (0, 0), và sau đó kiểm tra xem hình vuông "kết thúc" có phải là a không 1.


Điều này sẽ coi mê cung là có thể giải được nếu nó đã chứa 1 tại (n, m)?
trichoplax

2

Java, 418 byte

import java.util.Scanner;public class Solvable{static int w,h;public static void main(String[] a){String[]i=new Scanner(System.in).nextLine().split(";");h=i.length+2;w=i[0].length()+2;int[]m=new int[w * h];for(int x=1;x<w-1;x++)for(int y=1;y<h-1;y++)m[y*w+x]=i[y-1].charAt(x-1)<'.'?0:1;f(m,w+1);System.out.println(m[w*h-w-2]>0?0:1);}static void f(int[]m,int i){if(m[i]>0){m[i]--;f(m,i-1);f(m,i+1);f(m,i-w);f(m,i+w);}}}

Mã golf đầu tiên của tôi. Tôi không biết tại sao tôi chọn Java - thật tệ khi chơi golf xD

Ví dụ mê cung sẽ được nhập thông qua stdin như thế này:

......#;.....#.;....#..;#......

1
Pro tip: tên một nhân vật đẳng cấp một cái gì đó của bạn dài, mương khoảng trống giữa String[]a, và lấy ý kiến từ đối số dòng lệnh chứ không phải là stdin, mà được cho phép.
Pavel

1

Con trăn 184 188

def f(a,x=0,y=0,h=[]):s=h+[[x,y]];X,Y=len(a[0]),len(a);return([x,y]in h)==(x>=X)==(y>=Y)==(x<0)==(y<0)==a[y][x]<(x==X-1and y==Y-1or f(a,x-1,y,s)|f(a,x+1,y,s)|f(a,x,y-1,s)|f(a,x,y+1,s))

Điều này kéo dài hơn nhiều so với tôi nghĩ nó sẽ xảy ra :( Dù sao đi nữa, tôi sẽ thêm một lời giải thích một khi tôi không thể đánh golf nó nữa.


1

J, 75 ký tự

Cung cấp năng lượng cho ma trận kề (rất không hiệu quả về thời gian và bộ nhớ). (Có được gọi là powering trong tiếng Anh không?)

   ({.@{:@(+./ .*.^:_~)@(+:/~@,*2>(>@[+/@:|@:->@])"0/~@,@(i.@#<@,"0/i.@#@|:)))

Một số trường hợp thử nghiệm:

   m1=. 0 0 0 0 0 0 1,. 0 0 0 0 0 1 0,.  0 0 0 0 1 0 0,. 1 0 0 0 0 0 0
   m2=. 0 1 1 ,. 0 0 0
   m3=. 0 1 0 ,. 1 1 0
   m4=. 0 1 1 0 ,. 0 0 1 0
   ({.@{:@(+./ .*.^:_~)@(+:/~@,*2>(>@[+/@:|@:->@])"0/~@,@(i.@#<@,"0/i.@#@|:))) every m1;m2;m3;m4
1 1 0 0


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.