Mê cung vô tận


35

Lý lịch

Bạn là người học việc của một phù thủy mạnh mẽ và chủ nhân của bạn hiện đang phát triển một câu thần chú để tạo ra một mê cung giữa các chiều để nhốt kẻ thù của anh ta. Anh ta muốn bạn lập trình máy tính chạy bằng hơi nước của mình để phân tích các bố cục có thể. Lập trình cỗ máy ma quỷ này rất nguy hiểm, vì vậy bạn sẽ muốn giữ mã càng ngắn càng tốt.

Đầu vào

Đầu vào của bạn là một lưới hai chiều gồm các dấu .chấm và giá trị băm #, biểu thị không gian trống và các bức tường, được đưa ra dưới dạng một chuỗi phân định dòng mới. Sẽ luôn có ít nhất một .và một# , và bạn có thể quyết định xem có một dòng mới hay không.

Lưới này là bản thiết kế của một mê cung vô tận, được tạo ra bằng cách sắp xếp vô hạn nhiều bản sao của lưới cạnh nhau. Mê cung được chia thành các hốc , là các thành phần được kết nối của các không gian trống (các không gian liền kề theo đường chéo không được kết nối). Ví dụ: lưới điện

##.####
...##..
#..#..#
####..#
##...##

kết quả trong mê cung sau (tiếp tục vô tận theo mọi hướng):

##.######.######.####
...##.....##.....##..
#..#..##..#..##..#..#
####..#####..#####..#
##...####...####...##
##.######.######.####
...##.....##.....##..
#..#..##..#..##..#..#
####..#####..#####..#
##...####...####...##
##.######.######.####
...##.....##.....##..
#..#..##..#..##..#..#
####..#####..#####..#
##...####...####...##

Mê cung đặc biệt này chứa một khoang có diện tích vô hạn. Mặt khác, bản thiết kế này dẫn đến một mê cung chỉ có các hốc hữu hạn:

##.####
##..###
####...
..####.
#..####

Đầu ra

Đầu ra của bạn sẽ là một giá trị trung thực nếu mê cung chứa một khoang vô hạn và giá trị giả nếu không. Lưu ý rằng mê cung có thể chứa cả khoang hữu hạn và vô hạn; trong trường hợp đó, đầu ra sẽ là sự thật.

Quy tắc

Bạn có thể viết một chương trình đầy đủ hoặc một chức năng. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép.

Các trường hợp kiểm tra bổ sung

Khoang vô hạn:

.#

#.#
...
#.#

#.###.#.###.#
#.#...#...#.#
#.#.#####.#.#
..#.#...#.#..
###.#.#.#.###
#...#.#.#...#
#.###.#.###.#

##.###
#..###
..##..
###..#
##..##

..#..#..#..#..#..#
.#..#..#..#..#..#.
#..#..#..#..#..#..

#.####.###.###.####
#...#..#...###..###
###.#..#.######..##
....####.#######...
###..###...########
##########.##....##
..###......##.##...
#.........##..#####
###########..###..#
#...........####..#
#.###########.##..#
#.##....##.....####
#.####.###.###.####

Khoang hữu hạn:

###
#.#
###

.#
#.

####
.#..
####

#.#.#
..#..
#####
..#..
#.#.#

#.#.#.#.#.#
..#...#.#..
###.###.###
..#.#......
#.#.#######
#.#.......#
#.#######.#
#.#.....#.#
#.#.#.#.#.#

##....#####
.#..#...##.
.##.#..#...
..###.###..
#..##.#####
#...##....#
#.#.#####.#
###..####.#
....####...
###...#####

###....##.#########
####...##....#...##
..####.#######.###.
....##..........##.
###..#####.#..##...
####..#..#....#..##
..###.####.#.#..##.
..###...#....#.#...
..####..##.###...##
#.####.##..#####.##
####...##.#####..##


###########
........#..
#########.#
..........#
.##########
.#.........
##.########
...#.......

Có một ký tự dòng mới?
FUZxxl

@FUZxxl Điều đó tùy thuộc vào bạn.
Zgarb 30/03/2015

Mê cung vô tận có thể là một đường thẳng đi đến vô tận.

1
@Neil Tôi không chắc ý của bạn là gì. Các ví dụ vô hạn thứ nhất và thứ hai có các dòng vô hạn, nhưng có ít nhất một .và một #trong đầu vào.
Zgarb

1
Thử thách thú vị, khó khăn hơn dường như
edc65

Câu trả lời:


2

JavaScript (ES6), 235 253

Phương pháp tương tự được sử dụng bởi @mac. Đối với mỗi ô miễn phí, tôi thử điền vào đệ quy, đánh dấu các ô đã sử dụng bằng tọa độ tôi đang sử dụng (có thể nằm ngoài mẫu ban đầu). Nếu trong quá trình điền tôi đến một ô đã được đánh dấu có tọa độ khác, thì tôi đang ở trong một đường dẫn vô tận.

Các cách kỳ quặc xử lý các modulo trong JS nó khá khó chịu.

L=g=>(
  g=g.split('\n').map(r=>[...r]),
  w=g[0].length,h=g.length,
  F=(x,y,t=((x%w)+w)%w,u=((y%h)+h)%h,v=g[u][t],k=0+[x,y])=>
    v<'.'?0:v>'.'?v!=k
    :[0,2,-3,5].some(n=>F(x+(n&3)-1,y+(n>>2)),g[u][t]=k),
  g.some((r,y)=>r.some((c,x)=>c=='.'&&F(x,y)))
)

Kiểm tra trong bảng điều khiển Firefox / FireBug

Vô hạn

['##.###\n#..###\n..##..\n###..#\n##..##'
,'#.#\n...\n#.#'
,'#.###.#.###.#\n#.#...#...#.#\n#.#.#####.#.#\n..#.#...#.#..\n###.#.#.#.###\n#...#.#.#...#\n#.###.#.###.#'
,'##.###\n#..###\n..##..\n###..#\n##..##'
,'#.####.###.###.####\n#...#..#...###..###\n###.#..#.######..##\n....####.#######...\n###..###...########\n##########.##....##\n..###......##.##...\n#.........##..#####\n###########..###..#\n#...........####..#\n#.###########.##..#\n#.##....##.....####\n#.####.###.###.####'
].forEach(g=>console.log(g,L(g)))

Đầu ra

"##.###
#..###
..##..
###..#
##..##" true

"#.#
...
#.#" true

"#.###.#.###.#
#.#...#...#.#
#.#.#####.#.#
..#.#...#.#..
###.#.#.#.###
#...#.#.#...#
#.###.#.###.#" true

"##.###
#..###
..##..
###..#
##..##" true

"#.####.###.###.####
#...#..#...###..###
###.#..#.######..##
....####.#######...
###..###...########
##########.##....##
..###......##.##...
#.........##..#####
###########..###..#
#...........####..#
#.###########.##..#
#.##....##.....####
#.####.###.###.####" true

Có hạn

['###\n#.#\n###', '.#\n#.', '####\n.#..\n####'
,'#.#.#\n..#..\n#####\n..#..\n#.#.#'
,'#.#.#.#.#.#\n..#...#.#..\n###.###.###\n..#.#......\n#.#.#######\n#.#.......#\n#.#######.#\n#.#.....#.#\n#.#.#.#.#.#'
,'##....#####\n.#..#...##.\n.##.#..#...\n..###.###..\n#..##.#####\n#...##....#\n#.#.#####.#\n###..####.#\n....####...\n###...#####'
,'###....##.#########\n####...##....#...##\n..####.#######.###.\n....##..........##.\n###..#####.#..##...\n####..#..#....#..##\n..###.####.#.#..##.\n..###...#....#.#...\n..####..##.###...##\n#.####.##..#####.##\n####...##.#####..##'
].forEach(g=>console.log(g,L(g)))

Đầu ra

"###
#.#
###" false

".#
#." false

"####
.#..
####" false

"#.#.#
..#..
#####
..#..
#.#.#" false

"#.#.#.#.#.#
..#...#.#..
###.###.###
..#.#......
#.#.#######
#.#.......#
#.#######.#
#.#.....#.#
#.#.#.#.#.#" false

"##....#####
.#..#...##.
.##.#..#...
..###.###..
#..##.#####
#...##....#
#.#.#####.#
###..####.#
....####...
###...#####" false

"###....##.#########
####...##....#...##
..####.#######.###.
....##..........##.
###..#####.#..##...
####..#..#....#..##
..###.####.#.#..##.
..###...#....#.#...
..####..##.###...##
#.####.##..#####.##
####...##.#####..##" false

Vâng, daft modulo cũng là một nỗi đau trong C #, nhưng tôi nghĩ rằng tôi đã tìm ra cách sử dụng nó tốt trong bản sao làm việc của mình với mã định hướng (Tôi sẽ chỉ đăng lại nếu tôi có thể nhận được 10% giảm hoặc tốt hơn): (j%4-1)%2đưa ra một mô hình lặp lại tốt đẹp.
VisualMelon

Tôi tin rằng các hàm không tên được cho phép, và do đó, trừ khi chức năng bao gồm một lệnh gọi đến chính nó (nó sẽ không xuất hiện), nó được phép không được tính L=vào số byte.
SuperJedi224

@ SuperJedi224 có lẽ bạn đúng, nhưng nó đủ ngắn như sau
edc65

21

C # - 423 375 byte

Hoàn thành chương trình C #, chấp nhận đầu vào qua STDIN, xuất "Đúng" hoặc "Sai" thành STDOUT nếu phù hợp.

Tôi không thể để Linq ở đó ... may mắn là việc xóa bỏ nó đã được đền đáp! Bây giờ nó theo dõi các ô được nhìn thấy và truy cập trong một mảng (dù chỉ nhìn vào số lượng hữu hạn của chúng). Tôi cũng đã viết lại mã định hướng, loại bỏ sự cần thiết của Lambda và nói chung làm cho mã trở nên khó hiểu hơn (nhưng với mức tiết kiệm byte đáng kể).

using C=System.Console;struct P{int x,y;static void Main(){int w=0,W,k=0,o,i,j;P t;string D="",L;for(;(L=C.ReadLine())!=null;D+=L)w=L.Length;for(i=W=D.Length;i-->0&k<W;){k=1;P[]F=new P[W];for(F[j=0].x=i%w+W*W,F[0].y=i/w+W*W;D[i]>35&j<k;)for(t=F[j++],o=1;o<5&k<W;t.y+=(o++&2)-1){t.x+=o&2;if(D[--t.x%w+t.y%(W/w)*w]>35&System.Array.IndexOf(F,t)<0)F[k++]=t;}}C.WriteLine(k>=W);}}

Đây là một tìm kiếm đầu tiên (không phải là vấn đề này) chỉ thực hiện cho đến khi nó bị mắc kẹt trong một hang động hữu hạn, hoặc nó quyết định hang động đủ lớn đến mức nó phải lớn vô cùng (khi nó có nhiều tế bào như hình chữ nhật ban đầu, điều này có nghĩa là phải có một đường dẫn từ một ô đến chính nó ở một nơi khác, mà chúng ta có thể tiếp tục đi theo mãi mãi).

Mã chưa được phân loại:

using C=System.Console;

struct P
{
    int x,y;

    static void Main()
    {
        int w=0, // w is the width
        W, // W is the length of the whole thing
        k=0, // k is visited count
        o, // o is offset, or something (gives -1,0 0,-1 +1,0 0,+1 t offset pattern)
        i, // i is the start cell we are checking currently
        j; // j is the F index of the cell we are looking at

        P t; // t is the cell at offset from the cell we are looking at

        string D="", // D is the map
        L;

        for(;(L=C.ReadLine())!=null; // read a line, while we can
            D+=L) // add the line to the map
            w=L.Length; // record the width

        for(i=W=D.Length;i-->0&k<W;) // for each cell
        {
            k=1;

            P[]F=new P[W]; // F is the list of visited cells,

            for(F[j=0].x=i%w+W*W,F[0].y=i/w+W*W; // there are reasons (broken modulo)
                D[i]>35&j<k;) // for each cell we've visited, until we've run out
                for(t=F[j++], // get the current cell
                    o=1; // o is just a counter which we use to kick t about
                    o<5& // 4 counts
                    k<W; // make sure we havn't filled F
                    t.y+=(o++&2)-1) // kick and nudge y, inc o
                {
                    t.x+=o&2; // kick x
                    if(D[--t.x%w+t.y%(W/w)*w]>35 // nudge x, it's a dot
                       &System.Array.IndexOf(F,t)<0) // and we've not seen it before
                        F[k++]=t; // then add it
                }
        }

        C.WriteLine(k>=W); // result is whether we visited lots of cells
    }
}

1
Có lẽ là lần đầu tiên tôi thấy một C#câu trả lời là người nhận được phiếu bầu hàng đầu ở đây.
Michael McGriff

1
Chính () trong struct, bây giờ thật dễ thương.
PTwr

10

Con trăn 2 - 258 210 244 byte

Kiểm tra đệ quy các đường dẫn, nếu ngăn xếp tràn trả về 1 (trung thực) thì trả về Không (falsey).

import sys
def k(s):
 a=len(s);m=[[c=='.'for c in b]*999for b in s.split('\n')]*999;sys.setrecursionlimit(a)
 for x in range(a*a):
  try:p(m,x/a,x%a)
  except:return 1
def p(m,x,y):
 if m[x][y]:m[x][y]=0;map(p,[m]*4,[x,x,x+1,x-1],[y+1,y-1,y,y])

1
Bạn có thể lưu một số byte bằng cách sử dụng ;cho các dòng trong p, vì bạn sẽ nhận được chúng trên cùng một dòng với if.
PurkkaKoodari

11
"Nếu stack overflow return true" - Tôi thích điều kiện kết thúc đệ quy đó :)
schnaader

3
Tôi không tin đây là một cách tiếp cận hợp lệ. Sử dụng ngăn xếp tràn để phát hiện vùng "vô hạn" sẽ tạo ra kết quả dương tính giả. Thông số kỹ thuật không nêu bất kỳ giới hạn nào đối với phạm vi đầu vào nhưng một cái gì đó như mê cung 300x300 dường như không hợp lý và có thể kèm theo các đường dẫn hữu hạn rất dài.
JohnE

4
Hầu như tất cả các mê cung hữu hạn cũng sẽ gây ra tràn ngăn xếp. Đây không phải là một chương trình hợp lệ.
PyRulez

@johne Cập nhật để giới hạn đệ quy theo thứ tự kích thước của mê cung. Thật không may đã thêm 34 byte nhưng nó phải chính xác ngay bây giờ (ít nhất là chính xác như một hack như thế này có thể).
Kyle Gullion

5

Con trăn 2 - 297 286 275 byte

Chọn một ô "mở" tùy ý để bắt đầu lấp lũ. Mê cung là vô hạn nếu trong quá trình lấp đầy, chúng tôi ghé thăm lại một ô mà chúng tôi đã truy cập, nhưng nó có tọa độ khác với lần truy cập trước. Nếu lũ lấp đầy toàn bộ khu vực mà không tìm thấy một tế bào như vậy, hãy thử một khu vực khác. Nếu một khu vực như vậy không thể được tìm thấy, mê cung là hữu hạn.

Đưa tệp để xử lý trên dòng lệnh, trả về mã thoát 1vô hạn và0 hữu hạn.

Trả về kết quả chính xác cho tất cả các trường hợp thử nghiệm.

import sys
e=enumerate
C=dict([((i,j),1)for i,l in e(open(sys.argv[1]))for j,k in e(l)if'.'==k])
while C:
 d={}
 def f(r,c):
  n=(r%(i+1),c%j)
  if n in d:return(r,c)!=d[n]
  if C.pop(n,0):d[n]=(r,c);return any(map(f,[r-1,r,r+1,r],[c,c+1,c,c-1]))
 if f(*C.keys()[0]):exit(1)

1
Bạn không thể cho rằng một số tế bào sẽ là thành viên của một hang động vô hạn, bạn có thể dễ dàng có cả hang động vô hạn và hữu hạn.
VisualMelon

2
@VisualMelon: xin lỗi, mô tả không hoàn toàn chính xác. Mã này thực sự kiểm tra mọi vùng có thể của các ô được liên kết với nhau, không chỉ một (như hiện tại được ngụ ý). Đó là vòng lặp while cuối cùng dành cho - chọn các vùng để kiểm tra trong khi vẫn còn bất kỳ ô nào chưa được kiểm tra.
Mac
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.