가장 큰 방에 있습니까?


29

소개

최근에 Pretty Good Software Company에서 채용 제안을 수락했습니다. 사무실 크기에 만족하지만 가장 큰 사무실이 있습니까? 당신이 들릴 때 동료의 사무실을 시선으로 보는 것만으로도 말하기가 어렵습니다. 이것을 알아내는 유일한 방법은 건물의 청사진을 조사하는 것입니다.

당신의 작업

건물의 평면도를 작성하고 사무실이 가장 큰지 여부를 나타내는 프로그램, 스크립트 또는 기능을 작성하십시오. 건물은 n x n 정사각형 이므로 평면도를 쉽게 읽을 수 있습니다.

입력은 n + 1 \n 구분 라인 으로 구성됩니다 . 첫 번째 줄에는 숫자 n 이 있습니다. 다음 n 줄은 건물의 평면도입니다. 간단한 예제 입력 :

6
......
.  . .
.X . .
.  . .
.  . .
......

평면도의 규칙은 다음과 같습니다.

  • .(ASCII 46) 벽을 나타내는 데 사용됩니다. (공백 [ASCII 32])은 열린 공간을 나타내는 데 사용됩니다.
  • 귀하는 X(ASCII 88)으로 표시됩니다. 당신은 당신의 사무실에 있습니다.
  • 평면도는 각각 n 개의 문자 가있는 n 줄 입니다.
  • 건물은 모든면에서 벽으로 완전히 둘러싸여 있습니다. 이는 두 번째 입력 라인 (평면도의 첫 번째 라인)과 마지막 입력 라인이 모두 .s 임을 의미합니다 . 또한 모든 평면도의 첫 문자와 마지막 문자가 .s 임을 의미합니다 .
  • 사무실 크기는 인접한 공간의 합으로 정의됩니다 (벽을 통하지 않고 N, S, E, W의 4 방향으로 이동하여 연속 됨).
  • 사무실 크기의 목적 상, 당신을 나타내는 X는 (공백) 으로 계산됩니다.
  • 4 <= n <= 80

사무실이 다른 모든 사무실보다 엄격하게 큰지 여부를 출력해야합니다. 출력은 선택한 프로그래밍 언어에서 True 또는 False를 명확하게 나타내며 0, null 및 비어있는 False를 나타내는 표준 규칙을 준수합니다. True는 사무실이 엄청나게 크다는 것을 의미합니다.

위 입력에 대한 샘플 출력 :

1

사무실은 8 평방 피트이고 다른 사무실은 4 평방 피트이기 때문입니다.

I / O 지침

  • stdin에서 입력을 읽고 stdout에 출력에 응답 할 수 있습니다.

또는

  • 입력은 함수에 대한 단일 문자열 인수 일 수 있으며 응답은 해당 함수의 리턴 값입니다.

자주하는 질문

  • 전체 건물은 벽과 사무실로 구성되어 있습니다.
  • 건물은 1 층에 불과합니다
  • 입력에 X가 보장되지만 공백이 보장되지는 않습니다. 당신은 1x1 사무실을 가질 수 있고 건물의 나머지는 벽입니다 (당신은 가장 큰 사무실을 가지고 있습니다! hooray!).

다른 예

10
..........
.   .  . .
.  .   . .
.  .   . .
. ..   . .
..       .
..........
.      X .
.        .
..........

여기에는 3 개의 사무실이 있고, 남쪽 사무실은 직사각형이고, 북서 사무실은 삼각형 (ish)이며 북동쪽 사무실은 이상하게 잘못 표시되어 있지만 여전히 사무실보다 큽니다. 출력은 False 여야합니다.

가장 짧은 코드 인 행복한 를 작성하는 것은 어려운 일입니다 !


좋은 문제 지정이지만 X입력 에 허용되는 최대 수를 추가 할 수 있습니다 . :)
Greg Hewgill

4
X는 하나뿐입니다. X는 "당신"이며 그 방이 당신의 방임을 나타냅니다.
turbulencetoo

답변:


11

루비 2.0, 133 자

@Ventero와의 협업. 구문 강조 표시기를 깨기 시작할 때 항상 좋은 신호입니다!

이것은 재귀 플러드 필 솔루션입니다. STDIN에서 읽고 STDOUT으로 출력합니다.

f=->*a{a.product([~n=$_.to_i,-1,1,n+1]){|p,d|a|=[p]if$_[p+=d]<?.}!=a ?f[*a]:a.size}
gets(p).scan(/ /){$*<<f[$`.size]}
p$*.max<f[~/X/]

Ideone에서 실행되는 것을 참조하십시오 .


1
아주 좋아요! 스 플랫을 f약간 다시 정렬하여 두 개의 문자를 더 저장할 수 있다고 생각합니다 f=->l{a=[*l];a.product([~n,-1,1,n+1]){|p,d|a|=[p+d]if$_[p+d]<?.};a!=l ?f[a]:l.size}. 내가 틀렸다면 정정 해줘하지만 실제로 문제의 길이를 포함하는 첫 번째 라인에 남아있는 경우에하는 것처럼 보인다 $_당신이 입력 구문 분석을 단축 할 수 있도록 것이다,gets$e;n=$_.to_i
Ventero 사용자

1
아, 더 좋아 :) 마지막 편집을 통해 또 하나 개의 개선 : gets(p)같은 p아무것도 반환하지 않습니다 nil인수없이 호출합니다.
Ventero

1
사실, 나는 앞서 말한 것을 되 찾는다. 초기 스 플랫 배열을 사용하면 product수신기를 반환하여 l완전히 제거 한다는 사실을 사용할 수 있습니다 . f=->*a{a.product([~n,-1,1,n+1]){|p,d|a|=[p+d]if$_[p+d]<?.}!=a ?f[*a]:a.size}불행히도 !=공간을 제거하기 위해 lhs와 rhs를 전환 할 수는 없습니다. 그렇지 않으면 양쪽이 수정되지 않은 배열을 가리 킵니다.
Ventero

1
마지막 개선 : 학대 String#scan와으로 ARGV가장 큰 방을 찾는 것이 약간 단축 될 수 있습니다. $_.scan(/ /){$*<<f[$.size]}; p $ *. max <f [~ / X /]`
Ventero

1
죄송합니다 다시 도청을 위해,하지만 난 사실에 할당을 인라인으로 :) ... 또 다른 개선을 발견 n으로 f같은과 [~n=$_.to_i,...], 당신이 다음에 첫 번째와 세 번째 라인을 결합 할 수 있습니다 gets(p).scan(...(134 개) 문자의 총.
Ventero

7

GolfScript (85 바이트)

n/(~.*:N:^;{{5%[0.^(:^N]=}/]}%{{{.2$*!!{[\]$-1=.}*}*]}%zip}N*[]*0-:A{.N=A@-,2*+}$0=N=

온라인 데모

여기에는 세 가지 섹션이 있습니다.

  1. 0벽을 나타내는 데 사용하는 2D 배열을 생성하는 초기 입력 변환 , N내 시작 위치를 나타내는 (전체 셀 수) 및 서로 열린 공간에 대한 숫자 사이의 고유 한 숫자.

    n/(~.*:N:^;{{5%[0.^(:^N]=}/]}%
    
  2. 홍수가 가득합니다.

    {{{.2$*!!{[\]$-1=.}*}*]}%zip}N*
    
  3. 마지막 계산. 이것은 배열에서 가장 일반적인 요소에 대한 변형을 사용하여 바이어스에 대한 타이 브레이커를 추가합니다 N.

    []*0-:A{.N=A@-,2*+}$0=N=
    

제출해 주셔서 감사합니다! CJam 번역 : qN/(~_*:T:U;{[{i5%[0_U(:UT] =}/]}%{{[{_2$*!!{[\]$W=_}*}*]}%z}T*:+0-:A{_T=A@-,2*+}$0=T=.
jimmy23013

3

자바 스크립트 (E6) 155 292

F=(a,n=parseInt(a)+1,x,y)=>[...a].map((t,p,b,e=0,f=p=>b[p]==' '|(b[p]=='X'&&(e=1))&&(b[p]=1,1+f(p+n)+f(p-n)+f(p+1)+f(p-1)))=>(t=f(p))&&e?y=t:t<x?0:x=t)|y>x

Ungolfed 기본 버전

F=a=>
{
  var k, max=0, my=0, k=1, t, n = parseInt(a)+1;
  [...a].forEach( 
    (e,p,b) =>
    {
       x=0;
       F=p=>
       {
          var r = 1;
          if (b[p] == 'X') x = 1;
          else if (b[p] != ' ') return 0;
          b[p] = k;
          [n,1,-n,-1].forEach(q => r+=F(q+p));
          return r;
       }
       t = F(p);
       if (t) {
          if (x) my = t;
          if (t > max) max = t;
          k++;
          console.log(b.join(''));
       }    
    }
  )
  return my >= max
}

테스트

파이어 폭스의 자바 스크립트 콘솔

F('6\n......\n. . .\n.X . .\n. . .\n. . .\n......')

1

F('10\n..........\n. . . .\n. . . .\n. . . .\n. .. . .\n.. .\n..........\n. X .\n. .\n..........\n')

0

두 번째 것은 1나에게도 (Firefox 30.0에서)
Christoph Böhmwalder

@HackerCow 왜 그런지 모르겠지만 테스트 코드에서 cat & paste하면 공백이 압축됩니다. 각 줄은 10 자 여야합니다.
edc65

3

C #, 444 372 / (342 감사 HackerCow) 바이트

오히려 점수가 낮고 파티에 늦었지만 효과가있는 것 같습니다. 가장 큰 사무실이 하나 있으면 1을, 그렇지 않으면 0을 출력합니다. 나는 아직 골프에 대해 매우 복잡하지 않았습니다. 입력 (첫 번째 루프)에서 분리 된 세트를 작성하고 각 세트의 크기를 높이고 (두 번째 루프) 내 세트가 가장 큰지 (세 번째 루프) 확인하여 작동합니다.

두 가지 버전이 제공됩니다. 하나는 컴파일 가능한 프로그램이며 명령 줄에서 입력을 받아들이고 다른 하나는 문자열을 입력으로 예상하고 int를 결과로 반환하는 함수입니다. 사용 절 등이 필요하지 않으며 어디서나 넣을 수 있어야합니다.

프로그램 372bytes :

using System;class P{static void Main(){int s=int.Parse(Console.ReadLine()),e=0,d=s*s,a=d;int[]t=new int[d],r=new int[d];Func<int,int>T=null,k=v=>t[T(v)]=t[v]>0?a:0;T=v=>t[v]!=v?T(t[v]):v;for(;a>0;)foreach(var m in Console.ReadLine()){a--;if(m!=46){t[a]=a;e=m>46?a:e;k(a+s);k(a+1);}}for(a=d;a-->2;)r[T(a)]++;for(;d-->1;)a=d!=T(e)&&r[d]>=r[T(e)]?0:a;Console.WriteLine(a);}}

기능 342 바이트 :

static int F(string g){var b=g.Split('\n');int s=int.Parse(b[0]),e=0,d=s*s,a=d;int[]t=new int[d],r=new int[d];System.Func<int,int>T=null,k=v=>t[T(v)]=t[v]>0?a:0;T=v=>t[v]!=v?T(t[v]):v;for(;a>0;)foreach(var m in b[a/s]){a--;if(m!=46){t[a]=a;e=m>46?a:e;k(a+s);k(a+1);}}for(a=d;a-->2;)r[T(a)]++;for(;d-->1;)a=d!=T(e)&&r[d]>=r[T(e)]?0:a;return a;

덜 골프 :

using System;

class P
{
    static int F(string g)
    {
        var b=g.Split('\n');
        int s=int.Parse(b[0]),e=0,d=s*s,a=d;
        int[]t=new int[d],r=new int[d];
        System.Func<int,int>T=null,k=v=>t[T(v)]=t[v]>0?a:0;
        T=v=>t[v]!=v?T(t[v]):v;

        for(;a>0;)
            foreach(var m in b[a/s])
            {
                a--;
                if(m!=46)
                {
                    t[a]=a;
                    e=m>46?a:e;
                    k(a+s);
                    k(a+1);
                }
            }
        for(a=d;a-->2;)
            r[T(a)]++;
        for(;d-->1;)
            a=d!=T(e)&&r[d]>=r[T(e)]?0:a;
        return a;
    }

    static void Main()
    {
        /* F() test
        var s=Console.ReadLine();
        int i=int.Parse(s);
        for(;i-->0;)
        {
            s+="\n"+Console.ReadLine();
        }
        Console.WriteLine(F(s));*/


        int s=int.Parse(Console.ReadLine()),e=0,d=s*s,a=d;
        int[]t=new int[d],r=new int[d];
        Func<int,int>T=null,k=v=>t[T(v)]=t[v]>0?a:0;
        T=v=>t[v]!=v?T(t[v]):v;

        for(;a>0;)
            foreach(var m in Console.ReadLine())
            {
                a--;
                if(m!=46)
                {
                    t[a]=a;
                    e=m>46?a:e;
                    k(a+s);
                    k(a+1);
                }
            }
        for(a=d;a-->2;)
            r[T(a)]++;
        for(;d-->1;)
            a=d!=T(e)&&r[d]>=r[T(e)]?0:a;
        Console.WriteLine(a);
    }
}

1
실제로 작업 프로그램을 작성할 필요가 없다는 것을 이해 한 것처럼 함수로 충분합니다. 당신이 전에 모든 물건을 떨어 뜨리면 그래서 Main기능과 함께 기능을 대체 할 말을 int f(string s)당신이 사용할 수있는 s.Split('\n')[0]대신 Console.ReadLine()반환 및 10. 이렇게 하면 많은 코드를 절약 할 수 있습니다
Christoph Böhmwalder

@HackerCow 감사합니다, 나는 그 절을 완전히 놓쳤습니다! 다음 편집에 함수 버전을 넣겠습니다.
VisualMelon

2

CJam, 106 바이트

홍수 채우기에 대한 다른 접근 방식. 그래도 더 길어집니다 ...

liqN-'Xs0aer\_:L*{_A=' ={[AAL-A(]1$f=$:D1=Sc<{D2<(aer}*D0=_' ={T):T}@?A\t}*}fAT),\f{\a/,}_$W%_2<~>@@0=#0=&

여기 사용해보십시오


제출해 주셔서 감사합니다. 그러나 프로그램은 다음 입력으로 예외를 throw합니다. pastebin.com/v989KhWq
jimmy23013

@ user23013 수정되었습니다.
Optimizer

이러한 시도 pastebin.com/WyRESLWE
jimmy23013

2

파이썬 2-258 바이트

r=range;h=input();m="".join(raw_input()for x in r(h))
w=len(m)/h;n=0;f=[x!='.'for x in m]
for i in r(w*h):
 if f[i]:
    a=[i];M=s=0
    while a:
     i=a.pop();s+=1;M|=m[i]=='X';f[i]=0
     for j in(i-1,i+1,i-w,i+w):a+=[[],[j]][f[j]]
    n=max(s,n)
    if M:A=s
print A==n

입력을 위해 stdin을 사용합니다

참고 : 먼저 if단일 공백으로 들여 쓰기되고 다른 들여 쓰기 행은 단일 탭 문자 또는 탭과 공백을 사용합니다.


1

J : 150 121 바이트

(({~[:($<@#:I.@,)p=1:)=([:({.@#~(=>./))/@|:@}.({.,#)/.~@,))(>./**@{.)@(((,|."1)0,.0 _1 1)&|.)^:_[(*i.@:$)2>p=:' X'i.];._2

편집 : id그리고 comp엄청나게 복잡하고 느 렸습니다. 이제 cut( ;.)를 사용하여 3x3 창으로 스캔하는 대신지도를 4 번 이동합니다 .

청사진을 문자열로 인수로 사용합니다. 아래에 설명되어 있습니다 :

    s =: 0 :0
..........
.   .  . .
.  .   . .
.  .   . .
. ..   . .
..       .
..........
.      X .
.        .
..........
)
p=:' X' i. ];._2 s                NB. 0 where space, 1 where X, 2 where wall
id=:*i.@:$2>p                     NB. Give indices (>0) to each space
comp =: (>./ * *@{.)@shift^:_@id  NB. 4 connected neighbor using shift
  shift =: ((,|."1)0,.0 _1 1)&|.  NB. generate 4 shifts
size=:|:}.({.,#)/.~ , comp        NB. compute sizes of all components
NB. (consider that wall is always the first, so ditch the wall surface with }.)
NB. is the component where X is the one with the maximal size?
i=: $<@#:I.@,                     NB. find index where argument is 1
(comp {~ i p=1:) = {.((=>./)@{: # {.) size

NB. golfed:
(({~[:($<@#:I.@,)p=1:)=([:({.@#~(=>./))/@|:@}.({.,#)/.~@,))(>./**@{.)@(((,|."1)0,.0 _1 1)&|.)^:_[(*i.@:$)2>p=:' X'i.];._2 s
0

0

파이썬 2-378 바이트

와우. 연습이 없습니다.

def t(l,x,y,m,c=' '):
 if l[y][x]==c:l[y][x]=m;l=t(l,x-1,y,m);l=t(l,x+1,y,m);l=t(l,x,y-1,m);l=t(l,x,y+1,m)
 return l
def f(s):
 l=s.split('\n');r=range(int(l.pop(0)));l=map(list,l);n=1
 for y in r:
    for x in r:l=t(l,x,y,*'0X')
 for y in r:
  for x in r:
    if l[y][x]==' ':l=t(l,x,y,`n`);n+=1
 u=sum(l,[]).count;o=sorted(map(u,map(str,range(n))));return n<2or u('0')==o[-1]!=o[-2]

이것은 함수 답변이지만 전역 네임 스페이스를 오염시킵니다. 허용되지 않는 경우 1 바이트의 비용으로 고정 할 수 있습니다.

  • 줄 1의 시작 부분에 공백을 추가하십시오 (+1)
  • 2 행과 3 행의 시작 부분의 공백을 탭 문자 (+0)로 바꾸십시오.
  • 4 행을 처음으로 이동 (+0)

나는 전체 긴 설명을 작성했지만 분명히 제대로 저장되지 않았으며 다시는하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.