Sonsuz Labirentler


35

Arka fon

Siz güçlü bir sihirbazın çırağı sizsiniz ve efendiniz şu anda düşmanlarını yakalamak için boyutlar arası bir labirent oluşturmak için bir büyü geliştiriyor. Olası düzenleri analiz etmek için buharla çalışan bilgisayarını programlamanızı istiyor. Bu şeytani makineyi programlamak son derece tehlikelidir, bu nedenle kodu mümkün olduğunca kısa tutmak isteyeceksiniz.

Giriş

.Girişiniz #, yeni satırla sınırlandırılmış bir dize olarak verilen, boş alanı ve duvarları işaret eden iki boyutlu bir dönemler ve kareler ızgarasıdır . Her zaman en az bir tane olacak .ve #izleyen bir yeni satır olup olmadığına karar verebilirsiniz.

Bu ızgara, sonsuz sayıda labirentin planıdır ve bu, kılavuzun sonsuz sayıda kopyasını yan yana getirerek yapılır. Labirent, boş alanların (çapraz olarak bitişik alanların bağlanmadığı) bağlı bileşenleri olan boşluklara bölünmüştür . Örneğin, ızgara

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

aşağıdaki labirentte sonuçlanır (her yöne sonsuza dek devam eder):

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

Bu özel labirent, sonsuz alan boşluğu içerir. Öte yandan, bu plan sadece sonlu boşluklara sahip bir labirent ile sonuçlanmaktadır:

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

Çıktı

Labirentiniz sonsuz bir boşluk içeriyorsa çıktınız bir gerçek değer, değilse de sahte bir değer olacaktır. Labirentin hem sonlu hem de sonsuz boşluklar içerebileceğini unutmayın; Bu durumda, çıktı truthy olacaktır.

kurallar

Tam bir program veya bir fonksiyon yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklar izin verilmez.

Ek Test Durumları

Sonsuz boşluklar:

.#

#.#
...
#.#

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

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

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

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

Sonlu boşluklar:

###
#.#
###

.#
#.

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

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

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

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

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


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

Sonunda yeni bir satır var mı?
FUZxxl

@ FUZxxl Bu size kalmış.
Zgarb

Sonsuz labirent sonsuzluğa giden düz bir çizgi olabilir mi.

1
@Neil Ne demek istediğinden emin değilim. Birinci ve ikinci sonsuz örnekler sonsuz çizgilere sahiptir, ancak girişte en az bir .ve bir tane var #.
Zgarb

1
Güzel bir meydan okuma, göründüğünden daha zor
edc65

Yanıtlar:


2

JavaScript (ES6), 235 253

@Mac tarafından kullanılan aynı yöntem. Her boş hücre için, kullandığım koordinatı (orijinal şablonun dışında olabilir) kullanılan kullanılmış hücreleri işaretleyerek, özyinelemeli bir dolum denerim. Doldurma sırasında zaten farklı bir koordinat ile işaretlenmiş bir hücreye ulaşırsam, sonsuz bir yoldayım.

İlginç bir yol modulo taşıma JS oldukça sinir bozucu.

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

Firefox / FireBug konsolunda test edin

Sonsuz

['##.###\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)))

Çıktı

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

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

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

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

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

sınırlı

['###\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)))

Çıktı

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

".#
#." false

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

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

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

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

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

Evet, daft modulo, C # 'da da bir acıydı, ama çalışma kopyasımda yön koduyla iyi bir şekilde yararlanmanın bir yolunu buldum (sadece% 10 alırsam yeniden göndereceğim) azaltma veya daha iyi): (j%4-1)%2güzel bir yinelenen desen verir.
VisualMelon

Adsız fonksiyonlara izin verilebileceğine inanıyorum ve bu nedenle, bir işlev kendine bir çağrı içermedikçe (görünmeyecek gibi) L=byte sayımına sayılmama izin verilebilir .
SuperJedi224

@ SuperJedi224 muhtemelen haklısınız, ama sonuçta olduğu gibi yeterince kısa
edc65

21

C # - 423 375 bayt

C # programını tamamlayın, STDIN üzerinden girdiyi kabul edin, "Doğru" veya "Yanlış" çıktılarını STDOUT'a uygun şekilde verin.

O Linq'i orada bırakarak çıplak kalamadım ... Neyse ki çıkarılmaları ödendi! Şimdi bir dizideki görülen ve ziyaret edilen hücrelerin kaydını tutar (zaten sadece sınırlı sayıda gözüktüğü zaman). Ayrıca, bir Lambda gereksinimini ortadan kaldırarak ve genellikle kodu daha anlaşılması imkansız hale getiren (ancak önemli miktarda bayt tasarrufuyla), yönlü kodu yeniden yazdım.

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

Sonlu bir mağarada sıkışıp kalana kadar devam eden bir genişlik ilk (bu önemli değil) araştırmasıdır veya mağara, sonsuz büyüklükte olması gerektiği kadar büyük olduğuna karar verir (hücre kadar hücreye sahip olduğunda) orijinal dikdörtgen, bu demektir ki sonsuza kadar takip etmeye devam edebileceğimiz bir hücreden başka bir yere giden bir yol olmalı).

Unrimmed kodu:

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
Muhtemelen ilk kez C#burada en iyi oyu alan kişi olarak bir cevap gördüm .
Michael McGriff

1
Main () yapı olarak, şimdi bu sevimli.
PTwr

10

Python 2 - 258 210 244 bayt

Yığın taşması 1 (truthy) yoksa, None (falsey) döndürürse, yolları tekrar tekrar kontrol edin.

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
;Satırları kullanarak bazı baytları kaydedebilirsiniz p, çünkü bunları aynı satırda bulabilirsiniz if.
PurkkaKoodari

11
"Yığın taşması doğru olursa" - Bu yineleme son koşulunu
beğenirim

3
Bunun geçerli bir yaklaşım olduğuna ikna olmadım. "Sonsuz" bir bölgeyi tespit etmek için yığın taşmaları kullanmak yanlış pozitifler üretecektir. Sorun belirtimi, giriş aralıklarında herhangi bir sınırlama belirtmiyor ancak 300x300 labirent gibi bir şey mantıksız görünmüyor ve çok uzun sonlu yollar içerebiliyor.
JohnE,

4
Neredeyse tüm sonlu labirentler de istif taşmasına neden olur. Bu geçerli bir program değil.
PyRulez

@johne Güncellenme sınırı labirentlerin büyüklüğüne göre ayarlandı. Ne yazık ki 34 bayt eklendi, ancak şimdi doğru olmalı (en azından bunun gibi bir saldırı olabilir.
Kyle Gullion

5

Python 2 - 297 286 275 bayt

Bir sel dolgusu başlatmak için rastgele bir "açık" hücre seçer. Doldurma sırasında önceden ziyaret ettiğimiz bir hücreyi tekrar ziyaret edersek labirent sınırsızdır, ancak önceki ziyaret için farklı bir koordinatı vardır. Sel dolgusu, bu tür bir hücreyi bulmadan tüm bölgeyi dolduruyorsa, farklı bir bölge deneyin. Eğer böyle bir bölge bulunamazsa, labirent sonludur.

Komut satırında işlem yapmak için dosyayı alır, 1sınırsız ve 0sonlu için çıkış kodu döndürür .

Tüm test durumları için doğru sonuçları döndürür.

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
Herhangi bir hücrenin sonsuz bir mağaraya üye olacağını varsayamazsınız, kolayca hem sonsuz hem de sonlu mağaralara sahip olabilirsiniz.
VisualMelon

2
@VisualMelon: üzgünüm, açıklama tamamen doğru değil. Bu kod aslında birbirine bağlı hücrelerin her olası bölgesini kontrol eder, sadece birini değil (şu anda ima edildiği gibi). Kalan son döngü ise - kontrol edilmemiş herhangi bir hücre kalmışken kontrol edilecek bölgeleri seçmek.
Mac
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.