để tôi ra khỏi đây


12

Thử thách

Với kích thước lưới, vị trí của chướng ngại vật, vị trí người chơi và vị trí mục tiêu, nhiệm vụ của bạn là tìm đường dẫn để người chơi đến mục tiêu và tránh các chướng ngại vật cùng một lúc (nếu cần).

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


Đầu vào

  • N : Kích thước lướiN x N
  • P : Vị trí tin tưởng[playerposx, playerposy]
  • T : Vị trí của mục tiêu[targetposx, targetposy]
  • O : Vị trí của chướng ngại vật[[x1, y1], [x2, y2],...,[xn, yn]]

Đầu ra

Đường dẫn : Người chơi đường dẫn có thể sử dụng để tiếp cận mục tiêu[[x1, y1], [x2, y2],...,[xn, yn]]


Quy tắc

  1. Điểm [0,0]nằm ở góc trên cùng bên trái của lưới.
  2. Vị trí của người chơi sẽ luôn ở phía bên trái của lưới.
  3. Vị trí của mục tiêu sẽ luôn ở phía bên phải của lưới.
  4. Lưới sẽ luôn có ít nhất một trở ngại.
  5. Bạn có thể cho rằng không có chướng ngại vật nào đè lên người chơi hoặc vị trí mục tiêu.
  6. Bạn không nhất thiết phải tìm đường dẫn tối thiểu.
  7. Người chơi chỉ có thể di chuyển sang trái, phải, trên và dưới không theo đường chéo.
  8. Bạn có thể lấy đầu vào theo bất kỳ cách thuận tiện.
  9. Bạn có thể cho rằng một đường dẫn để người chơi đến mục tiêu sẽ luôn tồn tại.
  10. Rõ ràng, đối với mỗi đầu vào, nhiều đường dẫn hợp lệ tồn tại, chọn một đường dẫn.
  11. Giả sử N > 2như vậy lưới sẽ ít nhất 3 x 3.

Ví dụ

Input: 9, [6, 0], [3, 8], [[0, 5], [2, 2], [6, 4], [8, 2], [8, 7]]
có thể xảy ra Output:[[6, 0], [6, 1], [6, 2], [6, 3], [5, 3], [5, 4], [5, 5], [5, 6], [5, 7], [5, 8], [4, 8], [3, 8]]

Input: 6, [1, 0], [3, 5], [[1, 2], [2, 5], [5, 1]]
có thể xảy ra Output:[[1, 0], [1, 1], [2, 1], [2, 2], [2, 3], [2, 4], [3, 4], [3, 5]]


Ghi chú

Lưu ý rằng đó Xlà cho các hàng và Ycho cols. Đừng nhầm lẫn chúng với tọa độ trong một hình ảnh.

Biên tập

Như @digEmAll đã chỉ ra, do các quy tắc #2#3, playerY = 0targetY = N-1. Vì vậy, nếu bạn muốn, bạn chỉ có thể lấy làm đầu vào playerXvà và targetX(nếu điều đó làm cho mã của bạn ngắn hơn).


1
"Vị trí người chơi sẽ luôn ở bên trái và mục tiêu ở bên phải": điều này có nghĩa là người chơi-y = 0 và target-y = N-1? Nếu vậy, chúng ta có thể chấp nhận tọa độ x (một số) cho người chơi và mục tiêu không?
digEmAll

1
@digEmAll Điểm tốt. Thành thật mà nói, tôi đã không nghĩ về điều này và vâng, bạn có thể tôi sẽ chỉnh sửa nó.
DimChtz

Liên quan nhưng dễ dàng hơn. Liên quan nhưng khó hơn.
dùng202729

Là đường dẫn phải từ đầu đến cuối, hoặc nó có thể theo thứ tự ngược lại?
kamoroso94

1
@ kamoroso94 Có, bắt đầu nhắm mục tiêu (kết thúc) :)
DimChtz

Câu trả lời:


5

JavaScript (ES6), 135 byte

Lấy đầu vào là (width, [target_x, target_y], obstacles)(source_x, source_y), trong đó chướng ngại vật là một chuỗi các chuỗi có "X,Y"định dạng.

Trả về một chuỗi các chuỗi ở "X,Y"định dạng.

(n,t,o)=>g=(x,y,p=[],P=[...p,v=x+','+y])=>v==t?P:~x&~y&&x<n&y<n&[...o,...p].indexOf(v)<0&&[0,-1,0,1].some((d,i)=>r=g(x+d,y-~-i%2,P))&&r

Hãy thử trực tuyến!

Đã bình luận

(n, t, o) =>              // n = width of maze, t[] = target coordinates, o[] = obstacles
  g = (                   // g() = recursive search function taking:
    x, y,                 //   (x, y) = current coordinates of the player
    p = [],               //   p[] = path (a list of visited coordinates, initially empty)
    P = [                 //   P[] = new path made of:
      ...p,               //     all previous entries in p
      v = x + ',' + y     //     the current coordinates coerced to a string v = "x,y"
    ]                     //
  ) =>                    //
    v == t ?              // if v is equal to the target coordinates:
      P                   //   stop recursion and return P
    :                     // else:
      ~x & ~y             //   if neither x nor y is equal to -1
      && x < n & y < n    //   and both x and y are less than n
      & [...o, ...p]      //   and neither the list of obstacles nor the path
        .indexOf(v) < 0   //   contains a position equal to the current one:
      && [0, -1, 0, 1]    //     iterate on all 4 possible directions
        .some((d, i) =>   //     for each of them:
          r = g(          //       do a recursive call with:
            x + d,        //         the updated x
            y - ~-i % 2,  //         the updated y
            P             //         the new path
          )               //       end of recursive call
        ) && r            //     if a solution was found, return it

5

R , 227 byte

function(N,P,G,O){M=diag(N+2)*0
M[O+2]=1
b=c(1,N+2)
M[row(M)%in%b|col(M)%in%b]=1
H=function(V,L){if(all(V==G+2))stop(cat(L))
M[t(V)]=2
M<<-M
for(i in 0:3){C=V+(-1)^(i%/%2)*(0:1+i)%%2
if(!M[t(C)])H(C,c(L,C-2))}}
try(H(P+2,P),T)}

Hãy thử trực tuyến!

Không thực sự ngắn và chắc chắn không đưa ra con đường ngắn nhất (ví dụ kiểm tra ví dụ đầu tiên).
Về cơ bản, nó thực hiện tìm kiếm theo chiều sâu đệ quy và dừng ngay khi đạt được mục tiêu, in đường dẫn.

Cảm ơn JayCe vì đã cải thiện định dạng đầu ra


+1 Tôi thích cách bạn in đầu ra (không phải danh sách danh sách nhàm chán điển hình) :)
DimChtz

@DimChtz: cảm ơn rất nhiều nhưng ... đó là chức năng của trình trợ giúp, hàm golf-code chỉ in một danh sách tọa độ x1 y1 x2 y2 ... xn yn: D
digEmAll

1
Vâng, tôi biết: P nhưng vẫn tốt đẹp.
DimChtz

1
đồng ý với @DimChtz ... và tôi nghĩ nó thậm chí còn tốt hơn nếu bạn write(t(mx),1,N)thay vì printing :)
JayCe

@JayCe: ý kiến ​​hay, đã thay đổi!
digEmAll


3

Haskell , 133 131 130 byte

  • -1 byte nhờ vào BWO
(n!p)o=head.(>>=filter(elem p)).iterate(\q->[u:v|v@([x,y]:_)<-q,u<-[id,map(+1)]<*>[[x-1,y],[x,y-1]],all(/=u)o,x`div`n+y`div`n==0])

Hãy thử trực tuyến! (với một vài testcase)

Một chức năng !lấy làm đầu vào

  • n :: Int kích thước của lưới
  • p :: [Int] vị trí của người chơi như một danh sách [xp, yp]
  • o :: [[Int]] vị trí chướng ngại vật như một danh sách [[x1, y1], [x2, y2], ...]
  • t :: [[[Int]]](ẩn) vị trí của mục tiêu là một danh sách [[[xt, yt]]](danh sách ba chỉ để thuận tiện)

và trả về một đường dẫn hợp lệ như một danh sách [[xp, yp], [x1, y1], ..., [xt, yt]].

Như một phần thưởng, nó tìm thấy (một trong) con đường ngắn nhất và nó hoạt động cho vị trí của bất kỳ người chơi và mục tiêu nào. Mặt khác, nó rất không hiệu quả (nhưng các ví dụ được cung cấp chạy trong một khoảng thời gian hợp lý).

Giải trình

(n ! p) o =                                                         -- function !, taking n, p, o and t (implicit by point-free style) as input
    head .                                                          -- take the first element of
    (>>= filter (elem p)) .                                         -- for each list, take only paths containing p and concatenate the results
    iterate (                                                       -- iterate the following function (on t) and collect the results in a list
        \q ->                                                       -- the function that takes a list of paths q...
            [u : v |                                                -- ... and returns the list of paths (u : v) such that:
                v@([x, y] : _) <- q,                                -- * v is an element of q (i.e. a path); also let [x, y] be the first cell of v
                u <- [id, map (+ 1)] <*> [[x - 1,y], [x, y - 1]],   -- * u is one of the neighbouring cells of [x, y]
                all (/= u) o,                                       -- * u is not an obstacle
                x `div` n + y `div` n == 0                          -- * [x, y] is inside the grid
            ]
    )

iteratekk-1, bắt đầu với đường dẫn hợp lệ duy nhất có độ dài 1, đó là đường dẫn [[xt, yt]].

Biểu thức rõ ràng tối nghĩa [id, map (+ 1)] <*> [[x - 1,y], [x, y - 1]]chỉ là một phiên bản "golfy" (-1 byte) [[x + 1, y], [x, y + 1], [x - 1, y], [x, y - 1]].


2
Chào mừng đến với PPCG! Câu trả lời đầu tiên tốt đẹp!
Arnauld

1
@Arnauld Cảm ơn! Tôi thực sự đã dành vài giờ cố gắng vắt kiệt một vài byte trong giải pháp của mình chỉ để đánh bại 135 của bạn ^^
Delfad0r

1
Chơi golf tốt Bạn có thể lưu một byte bằng cách sử dụng toán tử thay vì hàm: Hãy thử trực tuyến!
ბიმო

@BWO Cảm ơn vì tiền boa. Tôi mới ở đây, vì vậy có nhiều thủ thuật tôi chưa từng nghe đến
Delfad0r

1
Btw. một phần với các mẹo cho Haskell, đặc biệt là nơi bạn có thể tìm thấy điều này và nhiều thủ thuật khác. Oh và luôn luôn trò chuyện: Của Monads and Men
ბიმო

1

Võng mạc 0.8.2 , 229 byte

.
$&$&
@@
s@
##
.#
{`(\w.)\.
$1l
\.(.\w)
r$1
(?<=(.)*)\.(?=.*¶(?<-1>.)*(?(1)$)\w)
d
}`\.(?=(.)*)(?<=\w(?(1)$)(?<-1>.)*¶.*)
u
+T`.`#`.(?=(.)*)(?<=d#(?(1)$)(?<-1>.)*¶.*)|(?<=(.)*.).(?=.*¶(?<-2>.)*(?(2)$)u#)|(?<=#r).|.(?=l#)
.(.)
$1

Hãy thử trực tuyến! Không chắc chắn định dạng I / O có đủ điều kiện hay không. Giải trình:

.
$&$&

Nhân đôi từng ô. Các bản sao bên trái được sử dụng như một khu vực làm việc tạm thời.

@@
s@

Đánh dấu sự bắt đầu của mê cung như đã viếng thăm.

##
.#

Đánh dấu sự kết thúc của mê cung là trống rỗng.

{`(\w.)\.
$1l
\.(.\w)
r$1
(?<=(.)*)\.(?=.*¶(?<-1>.)*(?(1)$)\w)
d
}`\.(?=(.)*)(?<=\w(?(1)$)(?<-1>.)*¶.*)
u

Trong khi các ô làm việc có sẵn tồn tại, hãy trỏ chúng đến các ô được truy cập trước đó.

+T`.`#`.(?=(.)*)(?<=d#(?(1)$)(?<-1>.)*¶.*)|(?<=(.)*.).(?=.*¶(?<-2>.)*(?(2)$)u#)|(?<=#r).|.(?=l#)

Theo dõi đường dẫn từ lối ra đến điểm bắt đầu bằng cách sử dụng các ô làm việc như một hướng dẫn.

.(.)
$1

Xóa các ô làm việc.


1

JavaScript, 450 byte

Đưa đầu vào là (n, {playerx, playery}, {targetx, targety}, [{obstaclex, obstacley}]). Trả về một mảng{hopx, hopy} .

j=o=>JSON.stringify(o);l=a=>a.length;c=(a,o)=>{let i=l(a);while(i>0){i--;if(j(a[i])==j(o)){return 1;}}return 0;}h=(p,t,o)=>{if(p.y<t.y&&!c(o,{x:p.x,y:p.y+1})){return{x:p.x,y:p.y+1};}if(p.y>t.y&&!c(o,{x:p.x,y:p.y-1})){return{x:p.x,y:p.y-1};}if(p.x<t.x&&!c(o,{x:p.x+1,y:p.y})){return{x:p.x+1,y:p.y};}if(p.x>t.x&&!c(o,{x:p.x-1,y:p.y})){return{x:p.x-1,y:p.y};}return t;}w=(n,p,t,o)=>{let r=[];r.push(p);while(j(p)!==j(t)){p=h(p,t,o);r.push(p);}return r;}

Đây là một phiên bản chưa được kiểm chứng về mớ hỗn độn của tôi:

// defining some Array's function for proper comparaisons
json = (object) => { return JSON.stringify(object) };
length = (array) => { return array.length; }
contains = (array, object) => {
    let i = length(array);
    while (i > 0) {
    i--;
        if (json(array[i]) == json(object)) { return true; }
    }
    return false;
}
//return next found hop
getNextHop = (player, target, obstacles) => {
    //uggly serie of conditions
    //check where do we have to go and if there is an obstacle there
    if(player.y<target.y && !contains(obstacles, [x:player.x, y:player.y+1])) { return [x:player.x, y:player.y+1]; }
    if(player.y>target.y && !contains(obstacles, [x:player.x, y:player.y-1])) { return [x:player.x, y:player.y-1]; }
    if(player.x<target.x && !contains(obstacles, [x:player.x+1, y:player.y])) { return [x:player.x+1, y:player.y]; }
    if(player.x>target.x && !contains(obstacles, [x:player.x-1, y:player.y])) { return [x:player.x-1, y:player.y]; }
    return target;
}
//return found path
getPath = (gridsize, player, target, obstacles) => {
    let path = [];
    path.push(player);
    //while player is not on target
    while(json(player)!=json(target)) {
        player = getNextHop(player, target, obstacles); //gridsize is never used as player and target are in the grid boundaries
        path.push(player);
    }
    return path;
}
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.