無限の迷宮


35

バックグラウンド

あなたは強力なウィザードの見習いであり、あなたのマスターは現在、彼の敵を閉じ込めるための次元間迷宮を作成するための呪文を開発しています。この悪魔のような機械をプログラミングすることは非常に危険なので、可能な限りコードを短くする必要があります。

入力

入力は、ピリオド.とハッシュの2次元グリッドで#、空行と壁を表し、改行で区切られた文字列として指定されます。常に少なくとも1つと1つ.あり#、末尾の改行があるかどうかを決定できます。

このグリッドは、無限の迷路の設計図であり、無限に並んだグリッドのコピーを無限に並べることによって作成されます。ラビリンスは、空のスペースの接続されたコンポーネントであるキャビティに分割されます(斜めに隣接するスペースは接続されません)。たとえば、グリッド

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

次のラビリンスが発生します(すべての方向に無限に続きます)。

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

この特定のラビリンスには、無限の面積の空洞が含まれています。一方、この設計図は、有限のキャビティのみを備えた迷路になります。

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

出力

ラビリンスに無限の空洞が含まれる場合、出力は真実の値になり、含まれない場合は偽の値になります。ラビリンスには、有限と無限の両方の空洞が含まれることがあります。その場合、出力は真実です。

ルール

完全なプログラムまたは関数を作成できます。最小のバイトカウントが優先され、標準の抜け穴は許可されません。

追加のテストケース

無限の空洞:

.#

#.#
...
#.#

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

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

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

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

有限キャビティ:

###
#.#
###

.#
#.

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

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

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

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

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


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

末尾の改行文字はありますか?
FUZxxl

@FUZxxlそれはあなた次第です。
ズガルブ

無限の迷路は、無限に向かう直線になりますか。

1
@Neilどういう意味かわかりません。最初と2番目の無限の例には無限の線がありますが、入力には少なくとも1 .#があります。
ズガルブ

1
見た目

回答:


2

JavaScript(ES6)、235 253

@macで使用されるのと同じメソッド。空きセルごとに再帰的な塗りつぶしを試み、使用中のセルに使用中の座標をマークします(元のテンプレートの外部にある場合もあります)。塗りつぶしの最中に、異なる座標を持つ既にマークされたセルに到着した場合、私は無限の道にいます。

風変わりな方法 JSで剰余を扱うのは、それは非常に迷惑なんです。

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コンソールでテストする

無限

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

出力

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

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

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

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

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

有限

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

出力

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

".#
#." false

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

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

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

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

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

ええ、ダフトモジュロはC#でも苦痛でしたが、方向コードを使用して作業コピーでそれをうまく利用する方法を見つけたと思います(10%を取得できる場合にのみ再投稿します削減またはそれ以上):(j%4-1)%2良い繰り返しパターンを提供します
VisualMelon

名前のない関数は許容されると考えます。したがって、thfunctionがそれ自体への呼び出しを含まない限り(そうではないように思われます)L=、バイトカウントに向かってカウントしないことは許容されます。
SuperJedi224

@ SuperJedi224あなたはおそらく正しいですが、結局のところ十分に短いです
-edc65

21

C#-423 375バイト

完全なC#プログラム。STDINを介して入力を受け入れ、必要に応じて「True」または「False」をSTDOUTに出力します。

私はそこにそのLinqを残しておくことができませんでした...ありがたいことに、その除去は報われました!配列内の表示されたセルと訪問されたセルを追跡するようになりました(とにかく限られた数のセルのみを参照する場合)。また、方向コードを書き直し、Lambdaの必要性をなくし、一般的にコードを理解しにくくしました(ただし、大幅にバイトを節約しました)。

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

これは幅が優先される(これは重要ではありません)検索で、有限の洞窟に閉じ込められるか、洞窟が無限に大きくなければならないほど大きくなると判断されるまで続行します(セルが元の長方形、これはあるセルからそれ自体へのパスがどこかになければならないことを意味します。

トリミングされていないコード:

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
おそらく、C#ここでトップ投票のゲッターとしての回答を見たのは初めてでしょう。
マイケルマクグリフ

1
構造体のMain()、かわいい
PTwr

10

パイソン2 - 258の 210 244バイト

スタックオーバーフローが1(真)を返す場合はパスを再帰的にチェックし、そうでない場合はNone(偽)を返します。

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
;の行にを使用すると、いくつかのバイトを節約pできますif
-PurkkaKoodari

11
「スタックオーバーフローがtrueを返す場合」-私はその再帰終了条件が好きです:)
schnaader

3
これが有効なアプローチであるとは確信していません。スタックオーバーフローを使用して「無限」領域を検出すると、誤検知が発生します。問題の仕様には入力範囲の制限は明記されていませんが、300x300の迷路のようなものは無理に思えず、非常に長い有限パスを囲むことができます。
JohnE

4
ほとんどすべての有限迷路もスタックオーバーフローを引き起こします。これは有効なプログラムではありません。
PyRulez

@johne更新して、再帰制限が迷路のサイズのオーダーになるようにしました。残念ながら34バイトを追加しましたが、今は正しいはずです(少なくとも、このようなハックと同じくらい正確です)。
カイルガリオン

5

Python 2-297 286 275バイト

塗りつぶしを開始する任意の「オープン」セルを選択します。ラビリンスは、塗りつぶし中に既に訪れたセルを再訪する場合は無限ですが、前回の訪問とは異なる座標を持ちます。塗りつぶしがそのようなセルを見つけることなく領域全体を満たす場合、別の領域を試してください。そのような領域が見つからない場合、ラビリンスは有限です。

コマンドラインで処理するファイルを受け取り1、無限および0有限の終了コードを返します。

すべてのテストケースの正しい結果を返します。

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
一部のセルが無限の洞窟のメンバーになるとは考えられません。無限の洞窟と有限の洞窟の両方を簡単に持つことができます。
VisualMelon

2
@VisualMelon:申し訳ありませんが、説明は完全には正しくありません。コードは、実際には1つだけではなく、相互接続されたセルのすべての可能な領域をチェックします(現在暗示されているように)。これが最終的なwhileループの目的です。未チェックのセルが残っている間にチェックする領域を選択します。
マック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.