Beni buradan çıkar


12

Meydan okuma

Bir ızgara boyutu, engellerin pozisyonları, oyuncu pozisyonu ve hedef pozisyonu göz önüne alındığında, göreviniz oyuncunun hedefe ulaşması ve aynı anda engellerden kaçınması için bir yol bulmaktır (gerekirse).

resim açıklamasını buraya girin


Giriş

  • N : Izgara boyutuN x N
  • P : Oyuncunun pozisyonu[playerposx, playerposy]
  • T : Hedefin konumu[targetposx, targetposy]
  • O : Engellerin konumları[[x1, y1], [x2, y2],...,[xn, yn]]

Çıktı

Yol : Hedefe ulaşmak için kullanabileceği bir yol oyuncusu[[x1, y1], [x2, y2],...,[xn, yn]]


kurallar

  1. Nokta [0,0], ızgaranın sol üst köşesinde bulunur.
  2. Oyuncunun pozisyonu daima ızgaranın sol tarafında olacaktır.
  3. Hedefin konumu her zaman ızgaranın sağ tarafında olacaktır.
  4. Izgara her zaman en az bir engele sahip olacaktır.
  5. Hiçbir engelin oyuncuyla veya hedef pozisyonla örtüşmediğini varsayabilirsiniz.
  6. Min yolunu bulmanız gerekmez.
  7. Oynatıcı çapraz olarak değil sadece sola, sağa, yukarı ve aşağı hareket edebilir.
  8. Girişi istediğiniz herhangi bir şekilde alabilirsiniz.
  9. Oyuncunun hedefe ulaşması için bir yolun her zaman var olacağını varsayabilirsiniz.
  10. Açıkçası, her giriş için birden fazla geçerli yol vardır, birini seçin.
  11. Şebekenin N > 2en azından olacağını varsayalım 3 x 3.

Örnekler

Girdi: 9, [6, 0], [3, 8], [[0, 5], [2, 2], [6, 4], [8, 2], [8, 7]]
Olası Çıktı:[[6, 0], [6, 1], [6, 2], [6, 3], [5, 3], [5, 4], [5, 5], [5, 6], [5, 7], [5, 8], [4, 8], [3, 8]]

Girdi: 6, [1, 0], [3, 5], [[1, 2], [2, 5], [5, 1]]
Olası Çıktı:[[1, 0], [1, 1], [2, 1], [2, 2], [2, 3], [2, 4], [3, 4], [3, 5]]


Not

Bunun Xsatırlar ve Ysütunlar için olduğunu unutmayın. Onları bir görüntüdeki koordinatlarla karıştırmayın.

Düzenle

As @digEmAll nedeniyle kurallarına, işaret #2ve #3, playerY = 0ve targetY = N-1. Yani, isterseniz sadece girdi olarak alabilir playerXve targetX(eğer kodunuzu kısaltırsa).


1
"Oyuncu pozisyonu her zaman sol tarafta ve hedef sağ tarafta olacak": bu oyuncu-y = 0 ve hedef-y = N-1 anlamına mı geliyor? Öyleyse, oyuncu ve hedef için x koordinatını (bir sayı) kabul edebilir miyiz?
digEmAll

1
@digEmAll İyi bir nokta. Dürüst olmak gerekirse, bunu düşünmedim ve evet bunu düzenleyebilirim.
DimChtz

İlgili ama daha kolay. İlgili ama daha zor.
user202729

Yol baştan sona mı olmalı yoksa ters sırada olabilir mi?
kamoroso94

1
@ kamoroso94 Evet, hedeflemeye başla (bitir) :)
DimChtz

Yanıtlar:


5

JavaScript (ES6), 135 bayt

Olarak girdi Alır (width, [target_x, target_y], obstacles)(source_x, source_y)nerede, engeller içinde dizelerden oluşan bir dizidir "X,Y"biçimi.

Biçimdeki bir dizi dizeyi döndürür "X,Y".

(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

Çevrimiçi deneyin!

Yorumlananlar

(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 bayt

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)}

Çevrimiçi deneyin!

Gerçekten kısa değil ve kesinlikle en kısa yolu vermiyor (örneğin ilk örneği kontrol edin).
Temelde yinelemeli bir derinlik ilk arama yapar ve hedefe ulaşılır ulaşılmaz durur, yolu yazdırır.

Çıktı biçimlendirmesindeki iyileştirme için JayCe'ye teşekkürler


+1 Çıktıları basma şeklinizi seviyorum (tipik sıkıcı liste listesini değil) :)
DimChtz

@DimChtz: çok teşekkürler ama ... bu yardımcı fonksiyon, kod-golf fonksiyonu sadece bir koordinat listesi yazdırıyor x1 y1 x2 y2 ... xn yn: D
digEmAll

1
Evet, biliyorum: P ama yine de güzel.
DimChtz

1
@DimChtz ile aynı fikirde ... ve ing write(t(mx),1,N)yerine daha iyi görünüyor düşünüyorum print:)
JayCe

@JayCe: iyi fikir, değişti!
digEmAll

4

Python 2 , 151149 bayt

N,s,e,o=input()
P=[[s]]
for p in P:x,y=k=p[-1];k==e>exit(p);P+=[p+[[x+a,y+b]]for a,b in((0,1),(0,-1),(1,0),(-1,0))if([x+a,y+b]in o)==0<=x+a<N>y+b>-1]

Çevrimiçi deneyin!


3

Haskell , 133 131 130 bayt

  • BWO sayesinde -1 bayt
(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])

Çevrimiçi deneyin! (birkaç test senaryosuyla)

!Girdi olarak alan bir işlev

  • n :: Int ızgaranın boyutu
  • p :: [Int] oyuncunun liste olarak konumu [xp, yp]
  • o :: [[Int]] engelleri liste olarak konumlandırma [[x1, y1], [x2, y2], ...]
  • t :: [[[Int]]](örtük) hedefin bir liste olarak konumu [[[xt, yt]]](sadece kolaylık olması için üçlü liste)

ve geçerli bir yolun liste olarak döndürülmesi [[xp, yp], [x1, y1], ..., [xt, yt]].

Bir bonus olarak, en kısa yollardan birini bulur ve herhangi bir oyuncunun ve hedefin pozisyonu için çalışır. Öte yandan, çok verimsizdir (ancak sağlanan örnekler makul bir sürede çalışır).

açıklama

(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
            ]
    )

iteratekk1[[xt, yt]]

Görünüşe göre belirsiz ifade [id, map (+ 1)] <*> [[x - 1,y], [x, y - 1]]sadece bir "golfy" (-1 bayt) sürümüdür [[x + 1, y], [x, y + 1], [x - 1, y], [x, y - 1]].


2
PPCG'ye Hoşgeldiniz! Güzel ilk cevap!
Arnauld

1
@Arnauld Teşekkürler! Aslında sadece senin 135 yenmek için benim çözüm dışında birkaç bayt sıkmak için birkaç saat geçirdim ^^
Delfad0r

1
Güzel golf! İşlev yerine bir işleç kullanarak bir bayt kaydedebilirsiniz: Çevrimiçi deneyin!
ბიმო

@BWO Tahmin için teşekkürler. Burada yeniyim, bu yüzden hiç duymadığım birçok püf noktası var
Delfad0r

1
Btw. orada bu ve daha birçok hileler bulabilirsiniz özellikle Haskell ilişkin ipuçlarını içeren bir bölüm. Oh ve her zaman sohbet de var: Monads and Men
ბიმო

1

Retina 0.8.2 , 229 bayt

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

Çevrimiçi deneyin! G / Ç formatının uygun olup olmadığından emin değilim. Açıklama:

.
$&$&

Her hücreyi çoğaltın. Sol kopya geçici bir çalışma alanı olarak kullanılır.

@@
s@

Labirentin başlangıcını ziyaret edilmiş olarak işaretleyin.

##
.#

Labirentin sonunu boş olarak işaretleyin.

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

Kullanılabilir çalışma hücreleri mevcut olsa da, onları daha önce ziyaret edilen hücrelere yönlendirin.

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

Çalışma hücrelerini kılavuz olarak kullanarak çıkıştan başlayarak yolu izleyin.

.(.)
$1

Çalışan hücreleri silin.


1

JavaScript, 450 bayt

Girişi alır (n, {playerx, playery}, {targetx, targety}, [{obstaclex, obstacley}]). Dizisini döndürür {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;}

İşte dağınıklığımda belirsiz bir sürüm:

// 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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.