Labirent çözülebilir mi?


20

Bulmaca

  • Bir labirent n * m çözülemiyorsa 0 yazdır
  • Bir labirent n * m çözülebilirse 1 yazdırın (1 veya daha fazla yolla)

(bu yüzden yollar istemiyorum ama çözmek mümkün ise !!!)

Giriş dizisi (2d):

[[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

Kural Başlangıç ​​konumu 0,0 ve bitiş konumu n, m Yalnızca yatay ve dikey olarak hareket edebilirsiniz En kısa kod kazanır


Girdi bir dize mi yoksa bir dizi mi olmalı?
apsillers

3
(N, m) 'de 1 (duvar) varsa kod 0 döndürmeli mi?
trichoplax

3
(Aynı duvar için (0,0)?)
Martin Ender

3
Bunun bir × labirent labirenti olduğunu söylüyorsunuz, ancak indekslemeniz bunun bir (n + 1) × (m + 1) labirent olduğunu ima ediyor.
Nick Matteo

3
Normal

Yanıtlar:


7

CJam, 42 41 39 36 35 bayt

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

Bu cevaptaki fikirlere dayanarak .

Optimizer sayesinde 4 bayt.

Giriş biçimi:

[[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 Bunun için teşekkürler. Ama sonra daha kısa bir yol buldum ...
jimmy23013

1
q2Wts~_s,{{[{_2$+0<{e<_}*}*]}%z}*sW=- 36. Girdinin ilk üç karakterinin olduğu varsayılmasına rağmen[[0
Optimizer

7

Dyalog APL, 27 karakter

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

değerlendirilmiş girdi. APL, bir matris ve bir vektör vektörü arasında ayrım yapar. Bu program, girdinin bir matris olduğunu varsayar.

(~×⍳∘⍴)Aeşit bir çatal (~A) × ⍳⍴A. İki kez bahsetmekten veya bir değişken getirmekten kaçınmak gerekir .

⍴Aşeklindedir A. 4'e 7 matris için şekil 4 7.

indeks üretecidir. ⍳4olduğunu 1 2 3 4. R4, 4'e 7 matrisinde düzenlenmiş ⍳4 7vektörlerdir (1 1)(1 2)...(4 7).

~Auçlarını çevirir A.

×⍳⍴Aters çevrilmiş bitlerle çarparak , tüm serbest hücrelerin koordinatlarını koruyoruz ve tüm duvarları dönüştürüyoruz 0 0.

,koordinat çiftlerinin matrisini ravel eder, yani onu bir vektöre doğrusallaştırır. Bu durumda, vektör çiftlerden oluşacaktır.

∘.-⍨Aveya A∘.-Aöğeleri Açift ​​olarak çıkarır . Burada öğelerinin Akendilerinin çift olduğunu unutmayın.

| mutlak değer

+/¨her mutlak değer çiftini toplayın. Bu bize labirentteki her hücre çifti arasındaki ızgara mesafelerini verir, duvarlar için tasarruf sağlar.

1≥sadece 1'den fazla olmayan bir mesafede komşularımızla ilgileniyoruz, bu da duvarları hariç tutuyor. Şimdi bir grafiğin bitişiklik matrisimiz var.

∨.∧⍨⍣≡ Floyd - Warshall'ın geçişli kapatma algoritması

(f⍣n)A(burada kullanılmaz) burada nbir tamsayı güç operatörüdür. Bu uygular fiçin A nzamanlarda: f f ... f A.

(f⍣g)Anerede gbir fonksiyon, sabit nokta operatörü, yani "güç limiti" dir. Bu dizi işlem devam ediyor A, f A, f f A, ... kadar ((f⍣i)A) g ((f⍣(i+1))A)bazıları için gerçek getiri i. Bu durumda match ( ) öğesini kullanırız g.

∨.∧⍨Aya A∨.∧Ada Floyd'un algoritmasında bir adımdır. f.gmatris çarpımı (bir genellemedir +.×), burada birleşim (kullanımı ) ve ayrım ( yerinde) +ve ×.

⊃⌽⍣≡Adımı yeterince kez uyguladıktan ve kararlı bir duruma ulaştıktan sonra , sonucu elde etmek için matrisin sağ üst köşesine bakmalıyız, bu yüzden onu çeviririz ( ) ve ilk, sol üstteki öğeyi ( ) alırız .

⍣≡Adımlarının görselleştirilmesi


5

Python, 164 bayt

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

Bunu göndermek için isteksizdim, çünkü normalde sel dolumunu nasıl yapacağım, sadece hafifçe golf oynadım. Ama işte zaten.


4

Perl, 73 bayt

69 bayt kod + 4 bayt -n0E(etiketlerin 2014'te nasıl sayıldığından emin değilim, bu yüzden onları 2 yerine 4 için saydım, ancak çok önemli değil).

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

Çevrimiçi deneyin! (Eğer değiştirirseniz ve 1111011çizgiyi 1111111, labirent artık çözülebilir değildir ve çıkış olacaktır 0yerine 1: ! çevrimiçi Deneyin )

açıklamalar:

Bu kod, labirentin ulaşılabilir her hücresini bulur (ve a ile işaretler A): bir hücre a ile işaretlenmiş bir hücreye dokunursa A, erişilebilir ve biz de işaretleriz A; ve bunu tekrar yapıyoruz ( redo). Bu iki regex sayesinde yapılır: s/(^0|A)(.{@{+}})?0/A$2A/sa'nın sağ veya alt kısmında boşluk olup olmadığını kontrol Aederken, s/0(.{@{+}})?A/A$1A/sa'nın solunda veya üstünde bir boşluk olup olmadığını kontrol eder A. Sonunda, son hücre içeriyorsa A(neyi en olduğunu aksi takdirde değil, o en ulaşılabilir say/A$/+0; çekler +0burada olduğundan emin sonuç olacaktır yapmak 0veya 1yerine boş dize ve 1).
Not /.*/bütün bir çizgi maç olacak, böylece ayarı@+bir satırın boyutu kadar olan bir .{@{+}}karakterin eşleşmesi için kullanılmasına izin veren bir satırın boyutu olan ilk satırın sonunun dizinine . ( @{+}regex'te eşdeğerdir @+, ancak yalnızca eskisi kullanılabilir)


İçin bu test durumda , kodunuz nihai pozisyon bile çözülebilir labirent düşünmektedir 1.
Jitse

@ İyi bir yakalama. Aslında, çünkü TIO bağlantıları doğru kodu kullanmıyordu (sanırım daha eski bir versiyonuydu ve ben tespit etmedim). Cevap hala geçerli ve TIO bağlantılarını güncelledim. Örneğin iyi çalışıyor: Çevrimiçi deneyin!
Dada

Ah, doğru! Açıklık için teşekkürler, bu yaklaşımı seviyorum.
Jitse

@ Teşekkürler, bu benim en sevdiğim golflerden biri :)
Dada

3

Yakut, 133 130 129 karakter

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]

STDIN, çıkışlar 1veya 0STDOUT üzerine giriş.

Can sıkıcı bir şekilde uzun. Sadece 1s'nin taşkın dolgusunu yapar (0, 0)ve sonra "bitiş" karesinin a olup olmadığını kontrol eder 1.


Bu zaten (n, m) 'de 1 varsa labirenti çözülebilir olarak değerlendirir mi?
trichoplax

2

Java, 418 bayt

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

İlk kodum golf. Java'yı neden seçtiğimi bilmiyorum - xD golf oynamak için çok kötü

Örnek labirent şu şekilde stdin ile girilir:

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

1
Profesyonel ipucu: Uzun sınıf şey bir karakter isim, arasında boşluk hendek String[]ve a, ve oldukça izin STDIN, daha komut satırı argümanları girdi alabilir.
Pavel

1

Python 184188

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

Bu olacağını düşündüğümden çok daha uzun sürdü :( Neyse, artık golf yapamadığımda bir açıklama ekleyeceğim.


1

J, 75 karakter

Bitişiklik matrisinin gücü (çok zaman ve bellek verimsiz). (Buna ingilizce güç denir mi?)

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

Bazı test örnekleri:

   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


0

Python 3 , 184 bayt

f=lambda m,x=0,y=0,n=0:n<len(m)*len(m[0])and m[x][y]<1and((x,y)==(len(m)-1,len(m[0])-1)or any(0<=i<len(m)and 0<=j<len(m[0])and f(m,i,j,n+1)for i,j in[(x-1,y),(x,y-1),(x+1,y),(x,y+1)]))

Çevrimiçi deneyin!

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.