무한 미로


35

배경

당신은 강력한 마법사의 견습생이며, 주인은 현재 적을 붙잡기 위해 차원 간 미로를 만드는 마법을 개발하고 있습니다. 그는 증기로 구동되는 컴퓨터를 프로그래밍하여 가능한 레이아웃을 분석하기를 원합니다. 이 악마 기계를 프로그래밍하는 것은 매우 위험하므로 코드를 최대한 짧게 유지해야합니다.

입력

입력은 개행으로 구분 된 문자열로 주어진 빈 공간과 벽을 나타내는 마침표 .와 해시 의 2 차원 격자입니다 #. 이 항상 적어도 하나가 될 것 .하나 #, 그리고 당신이 뒤에 줄 바꿈인지 여부를 결정할 수 있습니다.

이 격자는 무한한 미로의 청사진으로, 수많은 격자 사본을 서로 나란히 정렬하여 만들어집니다. 미로는 빈 공간의 구성 요소로 연결된 공동 으로 나뉩니다 (대각선으로 인접한 공간은 연결되지 않음). 예를 들어, 그리드

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

다음과 같은 미로를 만듭니다 (모든 방향으로 무한대로 계속됨).

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

이 특정 미로는 무한한 공간의 공동을 포함합니다. 반면에,이 청사진은 유한 한 공동 만있는 미로로 이어집니다.

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

산출

미로에 무한 캐비티가 포함되어 있으면 출력값이 진실한 값이되고 그렇지 않으면 거짓 값이됩니다. 미로에는 유한 공동과 무한 공동이 모두 포함될 수 있습니다. 이 경우 결과는 진실해야한다.

규칙

전체 프로그램이나 함수를 작성할 수 있습니다. 가장 낮은 바이트 수가 이기고 표준 허점은 허용되지 않습니다.

추가 테스트 사례

무한한 구멍 :

.#

#.#
...
#.#

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

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

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

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

유한 구멍 :

###
#.#
###

.#
#.

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

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

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

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

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


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

줄 바꿈 문자가 있습니까?
FUZxxl

@FUZxxl 그것은 당신에게 달려 있습니다.
Zgarb

무한한 미로가 무한대로가는 직선 일 수 있습니까?

1
@ 닐 무슨 말인지 잘 모르겠습니다. 첫 번째와 두 번째 무한 예제에는 무한 라인이 있지만 입력에 .하나 이상이 #있습니다.
Zgarb

1
멋진 도전, 생각보다 어려운
edc65

답변:


2

자바 스크립트 (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

예, daft modulo는 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#투표권을 얻는 사람이라고 대답 한 것을 본 적이있을 것입니다.
Michael McGriff

1
구조체의 Main (), 이제 귀엽습니다.
PTwr

10

파이썬 2 - (258) 210 244 바이트

스택 오버플로가 1 (거짓)을 반환하고 그렇지 않으면 (거짓)을 반환하면 경로를 재귀 적으로 확인하십시오.

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를 반환하는 경우"-재귀 종료 조건이 마음에
듭니다

3
이것이 올바른 접근법이라고 확신하지 않습니다. "무한한"영역을 감지하기 위해 스택 오버플로를 사용하면 오 탐지가 발생합니다. 문제 사양에는 입력 범위에 대한 제한이 명시되어 있지 않지만 300x300 미로와 같은 것은 합리적이지 않으며 매우 긴 유한 경로를 둘러 쌀 수 있습니다.
JohnE

4
거의 모든 유한 미로도 스택 오버플로를 일으킬 수 있습니다. 유효한 프로그램이 아닙니다.
PyRulez

@johne 재귀 제한이 미로 크기 정도가되도록 업데이트되었습니다. 불행히도 34 바이트가 추가되었지만 지금은 정확해야합니다 (적어도 이와 같은 해킹만큼 정확해야 함).
Kyle Gullion

5

파이썬 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 : 죄송합니다. 설명이 완전히 정확하지는 않습니다. 이 코드는 실제로는 하나가 아닌 상호 연결된 셀의 모든 가능한 영역을 검사합니다 (현재 암시되어 있음). 이것이 마지막 while 루프의 목적입니다. 아직 확인되지 않은 셀이 남아있는 동안 확인할 영역을 선택합니다.
Mac
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.