Gõ xuống các bức tường trong một mê cung


10

Quy tắc:

Trong trò chơi này, bạn bắt đầu ở trên cùng của một lưới hình chữ nhật có kích thước N x M được tạo thành từ các bức tường và không gian mở. Đầu vào là N dòng ký tự M, trong đó một .chỉ định một không gian mở và xchỉ định một bức tường. Chương trình của bạn sẽ xuất ra số K nhỏ nhất sao cho tồn tại một đường dẫn từ góc trên cùng bên trái đến góc dưới bên phải (không có đường chéo) đi qua tường K.

Ví dụ, đưa ra đầu vào:

..x..
..x..
xxxxx
..x..
..x..

chương trình của bạn sẽ xuất ra 2.

Những ví dụ khác:

đầu ra 4:

xxxxx
x.x.x
x.x.x
x..xx

đầu ra 0:

.xxxxxxxx
.x...x...
.x.x.x.x.
.x.x...x.
...xxxxx.

đầu ra 6:

xx
xx
xx
xx
xx

Các mẩu tin bổ sung:

Nếu nó làm cho cuộc sống của bạn dễ dàng hơn, bạn có thể chỉ định N và M làm tham số dòng lệnh.

Tín dụng bổ sung nếu bạn có thể yêu cầu chương trình của bạn in ra đường dẫn ở dạng này hay dạng khác.


4
: ngáp: Dijkstra, với một đống là V [2] [] và bộ đếm.
Peter Taylor

4
@Peter Taylor Nhưng bạn có thể tạo mã đó ngắn đến mức nào?
Migimaru

Câu trả lời:


3

Ruby 1.9 (235) (225) (222) (214)

Tôi không biết nếu chương trình này ngắn hơn một chương trình dựa trên Dijkstra, nhưng tôi đoán rằng tôi sẽ thử một cách tiếp cận khác. Điều này sử dụng regex trong một vòng lặp để đánh dấu mỗi không gian với số lượng tường tối thiểu cần thiết để tiếp cận nó.

w=".{#{/\s/=~s=$<.read}}?"
j="([.x])"
s[0]=v=s[0]<?x??0:?1
(d=v[-1];n=v.succ![-1]
0while(s.sub!(/#{j}(#{w+d})/m){($1<?x?d: n)+$2}||s.sub!(/(#{d+w})#{j}/m){$1+($2<?x?d: n)}))while/#{j}/=~q=s[-2]
p v.to_i-(q==n ?0:1)

Đầu vào được chỉ định là một tệp trên dòng lệnh, nghĩa là

> ruby1.9.1 golf.rb maze.txt

Ung dung:

# read in the file
maze = $<.read

# find the first newline (the width of the maze)
width = /\s/ =~ maze

# construct part of the regex (the part between the current cell and the target cell)
spaces = ".{#{width}}?"

# construct another part of the regex (the target cell)
target = "([.x])"

# set the value of the first cell, and store that in the current wall count
maze[0] = walls = (maze[0] == "x" ? "1" : "0")

# loop until the goal cell is not "." or "x"
while /#{target}/ =~ (goal = s[-2])

  # store the current wall count digit and the next wall count digit, while incrementing the wall count
  current = walls[-1]; next = walls.succ![-1]

  # loop to set all the reachable cells for the current wall count
  begin

    # first regex handles all cells above or to the left of cells with the current wall count
    result = s.sub!(/#{target}(#{spaces + current})/m) {
      ($1 == 'x' ? next : current) + $2
    }

    # second regex handles all cells below or to the right of cells with the current wall count
    result = result || s.sub!(/(#{current + spaces})#{target}/m) {
      $1 + ($2 == 'x' ? next : current)
    }
  end while result != nil
end

# we reached the goal, so output the wall count if the goal was a wall, or subtract 1 if it wasn't
puts walls.to_i - (goal == next ? 0 : 1)

2

Perl 5.10 (164)

undef$/;$_=<>;/\n/;$s="(.{$-[0]})?";substr$_,0,1,($n=/^x/||0);
until(/\d$/){1while s/([.x])($s$n)/$n+($1eq x).$2/se
+s/$n$s\K[.x]/$n+($&eq x)/se;$n++}
/.$/;print"$&\n"

Rất nhiều điều tương tự như giải pháp của Migimaru, chỉ với lần chạm Perl đó. 5.10 là cần thiết cho \Ktrong s///.


Điều này có xử lý đúng các mê cung đòi hỏi phải đi qua hơn 9 bức tường không?
Migimaru

@migimaru Không. Tôi có thể tăng nó lên tới 45 hoặc chỉ với số lượng nhân vật tăng khiêm tốn và số lượng gần như không giới hạn với một mức tăng nhỏ khác - nhưng nó sẽ không đẹp bằng.
hobbs

2

Python 406 378 360 348 418 ký tự

import sys
d={}
n=0
for l in open(sys.argv[1]):
 i=0
 for c in l.strip():m=n,i;d[m]=c;i+=1
 n+=1
v=d[0,0]=int(d[0,0]=='x')
X=lambda *x:type(d.get(x,'.'))!=str and x
N=lambda x,y:X(x+1,y)or X(x-1,y)or X(x,y+1)or X(x,y-1)
def T(f):s=[(x,(v,N(*x))) for x in d if d[x]==f and N(*x)];d.update(s);return s
while 1:
 while T('.'):pass
 v+=1
 if not T('x'):break
P=[m]
s,p=d[m]
while p!=(0,0):P.insert(0,p);x,p=d[p]
print s, P

Dijkstra đơn giản hóa, vì di chuyển với trọng lượng là trên xsân. Nó được thực hiện trong "sóng", vòng lặp đầu tiên với việc tìm .các trường chạm phía trước và đặt chúng trên cùng một trọng lượng, hơn một lần tìm xcác trường chạm phía trước và đặt chúng lên +1trọng lượng. Lặp lại trong khi không có nhiều trường không mong muốn.

Cuối cùng, chúng tôi biết trọng lượng cho mọi lĩnh vực.

Đầu vào được chỉ định là một tệp trên dòng lệnh:

python m.py m1.txt

Cập nhật: đường dẫn in.


1

Phiên bản C ++ (610 607 605 584)

#include<queue>
#include<set>
#include<string>
#include<iostream>
#include<memory>
#define S second
#define X s.S.first
#define Y s.S.S
#define A(x,y) f.push(make_pair(s.first-c,make_pair(X+x,Y+y)));
#define T typedef pair<int
using namespace std;T,int>P;T,P>Q;string l;vector<string>b;priority_queue<Q>f;set<P>g;Q s;int m,n,c=0;int main(){cin>>m>>n;getline(cin,l);while(getline(cin,l))b.push_back(l);A(0,0)while(!f.empty()){s=f.top();f.pop();if(X>=0&&X<=m&&Y>=0&&Y<=n&&g.find(s.S)==g.end()){g.insert(s.S);c=b[X][Y]=='x';if(X==m&&Y==n)cout<<-(s.first-c);A(1,0)A(-1,0)A(0,1)A(0,-1)}}}

Triển khai thuật toán của Dijkstra.

Chưa chơi gôn:

#include<queue>
#include<set>
#include<string>
#include<iostream>
#include<memory>

using namespace std;
typedef pair<int,int>P;
typedef pair<int,P>Q;

int main()
{
    int             m,n;
    string          line;
    vector<string>  board;

    cin >> m >> n;getline(cin,l);
    while(getline(cin,line))
    {
        board.push_back(line);
    }

    priority_queue<Q>   frontList;
    set<P>              found;
    frontList.push(make_pair(0,make_pair(0,0)));
    while(!frontList.empty())
    {
        Q s=frontList.top();
        frontList.pop();
        if(   s.second.first>=0
           && s.second.first<=m
           && s.second.second>=0
           && s.second.second<=n
           && found.find(s.second)==found.end()
        )
        {
            found.insert(s.second);
            int c=board[s.second.first][s.second.second]=='x';
            if(  s.second.first==m
              && s.second.second==n
            )
            {   cout<<-(s.first-c);
            }
            frontList.push(make_pair(s.first-c,make_pair(s.second.first+1,s.second.second)));
            frontList.push(make_pair(s.first-c,make_pair(s.second.first-1,s.second.second)));
            frontList.push(make_pair(s.first-c,make_pair(s.second.first,s.second.second+1)));
            frontList.push(make_pair(s.first-c,make_pair(s.second.first,s.second.second-1)));
        }
    }
}
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.