您在最大的房间吗?


29

介绍

您最近接受了Pretty Good Software Company的工作机会。您对办公室的大小很满意,但是您有吗最大的办公室?当您停下脚步时,仅盯着同事的办公室很难说清楚。解决这个问题的唯一方法是检查建筑物的蓝图。

你的任务

编写一个程序,脚本或功能,以制定建筑物的平面图并指出您的办公室是否最大。平面图很容易阅读,因为建筑物是n by n正方形。

输入将包含n + 1个 \n定界线。第一行的数字为n。接下来的n行将是建筑物的平面图。一个简单的示例输入:

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

平面图的规则如下:

  • .(ASCII 46)将用于表示墙壁。(空格[ASCII 32])将用于表示开放空间。
  • 您用X(ASCII 88)表示。你在办公室
  • 平面图将是n行,每行包含n个字符。
  • 建筑物四周四面都是墙。这意味着输入的第二行(平面布置图的第一行)和输入的最后一行均为.s。这也意味着每条平面图行的第一个和最后一个字符将是.s。
  • 办公室的大小定义为相邻空间的总和(通过在四个方向(N,S,E,W上移动而无需穿过墙壁而连续))。
  • 为了办公室的大小,代表您的X计为(开放空间)
  • 4 <= n <= 80

您应该输出您的办公室是否严格大于其他所有办公室。输出可以是在您选择的编程语言中明确表示True或False并遵循零,null和空表示False的标准约定的任何内容。真实意味着您的办公室绝对是最大的。

以上输入的样本输出:

1

因为您的办公室是8平方英尺,而另一个办公室是4平方英尺。

I / O准则

  • 可以从stdin读取输入,然后将输出应答到stdout。

要么

  • 输入可以是函数的单个字符串参数,答案是该函数的返回值。

常问问题

  • 整个建筑由墙壁和办公室组成。
  • 大楼只有一层
  • 输入中肯定有一个X,但不能保证有任何空格。您可以拥有一个1x1的办公室,而建筑物的其余部分是墙壁(您拥有最大的办公室!万岁!)。

其他例子

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

这里有3个办公室,您的南边办公室是矩形的,西北边的办公室是三角形的,而东北边的办公室奇怪地变形了,但比您的大。输出应为False。

编写最短的代码是一件很困难的事情,快乐


很好的问题说明,但是您可以X在输入中添加允许的最大数量。:)
Greg Hewgill 2014年

4
X只有一个。X是“您”,表示它所在的房间是您的房间。
turbulencetoo 2014年

Answers:


11

Ruby 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 2014年

1
啊,更好。:)比您上一次编辑的另一个改进:gets(p)p什么也不做,nil如果不带参数调用则返回。
Ventero 2014年

1
实际上,我收回了我之前说的话。使用您最初的splat安排,我们可以使用将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 2014年

1
最后一项改进:滥用String#scanARGV,找到最大的房间可以缩短一点:$_.scan(/ /){$*<<f[$.size]}; p $ *
。max

1
对不起,又缠着你,但我居然发现了另一个改进... :)通过分配到内联nf喜欢的东西[~n=$_.to_i,...],你可以再结合第一和第三行成gets(p).scan(...,共134个字。
Ventero 2014年

7

GolfScript(85字节)

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

在线演示

这包括三个部分:

  1. 初始输入转换生成一个2D数组,该数组0用于表示墙,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

Javascript(E6)155292

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

非高尔夫版

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
}

测试

Firefox中的Javascript控制台

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中)
ChristophBöhmwalder2014年

@HackerCow我不知道为什么,但是如果您从我的测试代码中删除并粘贴,则空格将被压缩。每行应为10个字符。
edc65

3

C#,444 372 /(342感谢HackerCow)字节

分数不高,到晚了聚会,但似乎奏效。如果拥有一个最大的办公室,则输出1;否则,则输出0。我对高尔夫还不太了解。通过从输入构建不相交的集合(第一个循环),计算每个集合的大小(第二个循环),然后查看我的集合是否最大(第三个循环)来工作。

提供了两个版本,一个是可编译程序tat接受来自命令行的输入,另一个是仅希望将字符串作为输入并返回int作为结果的函数(并且只是第一个的重做副本)-它不需要任何using子句等,应该可以将其放在任何地方,并且可以正常工作。

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

功能 342bytes

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()和return 10。这应该可以节省很多代码
ChristophBöhmwalder2014年

@HackerCow谢谢,我完全错过了该条款!我将在下次编辑中添加函数版本。
VisualMelon 2014年


2

Python 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

使用标准输入

注意:首先if用单个空格缩进,其他缩进行使用单个制表符char或制表符和空格。


1

Y:150个 121字节

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

编辑idcomp荒谬的复杂和缓慢。现在,它可以将地图移动4次,而不是使用cut;.)在3x3窗口中进行扫描。

将蓝图作为字符串作为参数。解释如下:

    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

Python 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)的开头添加一个空格
  • 用制表符(+0)替换第2和3行开头的空格
  • 将第4行移至开头(+0)

我写了一个很长的解释,但显然它没有正确保存,我也不再这样做了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.