คุณอยู่ในห้องที่ใหญ่ที่สุดเหรอ?


29

บทนำ

คุณเพิ่งตอบรับข้อเสนองานที่ บริษัท ซอฟต์แวร์สวย ๆ คุณพอใจกับขนาดของสำนักงานของคุณ แต่คุณมีขนาดใหญ่ที่สุดสำนักงานหรือไม่? มันยากที่จะบอกจากเพียงแค่ดวงตาของเพื่อนร่วมงานของคุณเมื่อคุณหยุด วิธีเดียวที่จะเข้าใจสิ่งนี้คือการตรวจสอบพิมพ์เขียวสำหรับอาคาร ...

งานของคุณ

เขียนโปรแกรมสคริปต์หรือฟังก์ชั่นที่ใช้แผนผังชั้นอาคารของคุณและระบุว่าสำนักงานของคุณใหญ่ที่สุดหรือไม่ แผนชั้นง่ายต่อการอ่านเพราะอาคารเป็นnโดยnตาราง

อินพุตจะประกอบด้วยบรรทัดที่มีการ จำกัดn + 1 \nบรรทัดแรกจะมีหมายเลขnอยู่ ถัดไปnเส้นจะแขวะสำหรับอาคาร อินพุตตัวอย่างง่ายๆ:

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

กฎสำหรับผังมีดังนี้:

  • .(ASCII 46) จะถูกใช้เพื่อแสดงถึงกำแพง (Space [ASCII 32]) จะถูกใช้เพื่อแสดงพื้นที่ว่าง
  • คุณเป็นตัวแทนของX(ASCII 88) คุณอยู่ในสำนักงานของคุณ
  • แปลนห้องจะเป็นnเส้นโดยแต่ละตัวมีอักขระnตัว
  • ตัวอาคารล้อมรอบด้วยกำแพงทุกด้าน นี่หมายความว่าอินพุตบรรทัดที่ 2 (บรรทัดแรกของแปลนห้อง) และบรรทัดสุดท้ายของอินพุตจะเป็น.s ทั้งหมด นอกจากนี้ยังแสดงให้เห็นว่าตัวอักษรตัวแรกและตัวสุดท้ายของทุกแผนผังแปลนจะเป็น.s
  • ขนาดสำนักงานถูกกำหนดให้เป็นผลรวมของช่องว่างที่อยู่ติดกัน (ต่อเนื่องกันโดยการเคลื่อนที่ใน 4 ทิศทางคือ N, S, E, W โดยไม่ต้องผ่านกำแพง)
  • สำหรับจุดประสงค์ของขนาดสำนักงานเครื่องหมาย X ที่คุณนับว่าเป็น(พื้นที่เปิดโล่ง)
  • 4 <= n <= 80

คุณควรส่งออกว่าสำนักงานของคุณใหญ่กว่าสำนักงานอื่น ๆ หรือไม่ เอาต์พุตสามารถเป็นอะไรก็ได้ที่บ่งบอกถึงความจริงหรือเท็จในภาษาการเขียนโปรแกรมที่คุณเลือกอย่างไม่น่าสงสัยและปฏิบัติตามอนุสัญญามาตรฐานที่เป็นศูนย์, ไม่มีค่า, และไม่มีความหมายที่ว่างเปล่า True หมายถึงสำนักงานของคุณนั้นใหญ่ที่สุดอย่างเคร่งครัด

ตัวอย่างเอาต์พุตสำหรับอินพุตด้านบน:

1

เนื่องจากที่ทำงานของคุณคือ 8 ตารางฟุตและที่ทำงานอีกแห่งหนึ่งคือ 4 ตารางฟุต

แนวทาง I / O

  • อินพุตอาจถูกอ่านจาก stdin และตอบเอาต์พุตไปยัง stdout

หรือ

  • อินพุตอาจเป็นอาร์กิวเมนต์สตริงเดี่ยวของฟังก์ชันและ answer เป็นค่าส่งคืนของฟังก์ชันนั้น

คำถามที่พบบ่อย

  • ทั้งอาคารประกอบด้วยผนังและสำนักงาน
  • อาคารมีเพียงชั้นเดียว
  • มีการรับประกันว่าจะเป็น X ในอินพุต แต่ไม่รับประกันว่าจะมีช่องว่างใด ๆ คุณอาจมีสำนักงาน 1x1 และอาคารที่เหลือเป็นผนัง (คุณมีสำนักงานที่ใหญ่ที่สุด! ไชโย!)

ตัวอย่างอื่น ๆ

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

ที่นี่มีสำนักงาน 3 แห่งสำนักงานภาคใต้ของคุณเป็นรูปสี่เหลี่ยมผืนผ้าสำนักงานภาคตะวันตกเฉียงเหนือเป็นรูปสามเหลี่ยม (ish) และสำนักงานภาคตะวันออกเฉียงเหนือเป็นรูปแบบที่ผิดแปลก แต่ใหญ่กว่าของคุณ ผลลัพธ์ควรเป็นเท็จ

นี่คือความท้าทายในการเขียนรหัสที่สั้นที่สุดและมีความสุขใน !


สเปคปัญหาที่ดี แต่คุณสามารถเพิ่มจำนวนสูงสุดที่Xอนุญาตในอินพุตได้ :)
Greg Hewgill

4
มีหนึ่ง X เท่านั้น X คือ "คุณ" และบ่งบอกว่าห้องนั้นเป็นของคุณ
turbulencetoo

คำตอบ:


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

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[$ขนาด]}; 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. การแปลงอินพุตเริ่มต้นซึ่งสร้างอาร์เรย์ 2 มิติโดยใช้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) 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

เวอร์ชันฐานที่ไม่ดี

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
}

ทดสอบ

คอนโซล Javascript ใน firefox

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

@ แฮ็กเกอร์โคว์ฉันไม่รู้ว่าทำไม แต่ถ้าคุณแมว & วางจากรหัสทดสอบของฉันพื้นที่สีขาวจะถูกบีบอัด แต่ละบรรทัดควรมี 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);}}

ฟังก์ชัน 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()และผลตอบแทนหรือ1 0สิ่งนี้จะช่วยให้คุณประหยัดรหัสได้มาก
Christoph Böhmwalder

@ แฮ็กเกอร์โควขอบคุณฉันพลาดประโยคนั้นโดยสิ้นเชิง! ฉันจะใส่รุ่นฟังก์ชั่นในการแก้ไขครั้งต่อไปของฉัน
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=&

ลองที่นี่


ขอบคุณสำหรับการส่ง แต่โปรแกรมของคุณส่งข้อยกเว้นด้วยอินพุตนี้: pastebin.com/v989KhWq
jimmy23013


ลองสิ่งเหล่านี้: pastebin.com/WyRESLWE
jimmy23013

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

ใช้ stdin สำหรับอินพุต

หมายเหตุ: อันดับแรกifถูกเยื้องโดยเว้นวรรคเดียวบรรทัดเยื้องอื่น ๆ อาจใช้อักขระแท็บเดี่ยวหรือแท็บและเว้นวรรค


1

J: 150 121 ไบต์

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

แก้ไข : idและcompมีความซับซ้อนขันและช้า ตอนนี้มันสามารถขยับแผนที่ได้ 4 ครั้งแทนที่จะสแกนด้วยหน้าต่าง 3x3 โดยใช้cut( ;.)

ใช้เป็นอาร์กิวเมนต์พิมพ์เขียวเป็นสตริง อธิบายด้านล่าง:

    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)
  • แทนที่ช่องว่างที่จุดเริ่มต้นของบรรทัดที่ 2 และ 3 ด้วยอักขระแท็บ (+0)
  • ย้ายบรรทัดที่ 4 ไปที่จุดเริ่มต้น (+0)

ฉันมีคำอธิบายที่เขียนมานาน แต่เห็นได้ชัดว่ามันไม่ได้บันทึกอย่างถูกต้องและฉันไม่ได้ทำอย่างนั้นอีกครั้ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.