En büyük odada mısın?


29

Giriş

Kısa süre önce Pretty Good Software Company'de bir iş teklifini kabul ettiniz. Ofisinizin büyüklüğünden oldukça memnunsunuz ama en büyük ofisiniz var mı? Uğraşırken iş arkadaşlarınızın ofisine göz atmaktan söylemek biraz zor. Bunu çözmenin tek yolu, binanın taslaklarını incelemektir.

Senin görevin

Binanız için bir kat planı alan ve ofisinizin en büyük olup olmadığını belirten bir program, komut dosyası veya işlev yazın. Kat planı bina olduğu için okumak kolaydır n tarafından n meydanda.

Giriş n + 1 ile \n sınırlandırılmış satırlardan oluşacaktır . İlk satırda n numarası bulunacaktır . Sonraki n satırları binanın kat planı olacaktır. Basit bir örnek giriş:

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

Yer planı için kurallar aşağıdaki gibidir:

  • .(ASCII 46) Duvarları temsil etmek için kullanılacaktır. (Boşluk [ASCII 32]) açık boşluğu temsil etmek için kullanılacaktır.
  • Bir X(ASCII 88) ile temsil edilirsiniz. Sen ofisindesin.
  • Floorplan olacak n hatları, her biriyle n karakterleri.
  • Bina tamamen her tarafı duvarlarla çevrilidir. Bu, 2. girdi satırının (yer planının ilk satırı) ve son girdi satırının hepsinin olacağı anlamına gelir .. Ayrıca, her yer planı çizgisinin ilk ve son karakterlerinin .s olacağı anlamına gelir .
  • Bir ofis büyüklüğü, bitişik alanların toplamı olarak tanımlanır (bir duvardan geçmeden, N, S, E, W, 4 yönde hareket ettirilerek bitişik).
  • Ofis boyutunda, sizi temsil eden X, (açık alan) olarak sayılır.
  • 4 <= n <= 80

Ofisinizin kesinlikle diğer tüm ofislerden daha büyük olup olmadığına karar vermelisiniz. Çıktı, seçtiğiniz programlama dilinizde açıkça veya Yanlış olarak belirten ve sıfır, boş ve boş belirten False standart kurallarına uyan herhangi bir şey olabilir. Doğru, ofisinizin kesinlikle en büyük olduğu anlamına gelir.

Yukarıdaki giriş için örnek çıktı:

1

Çünkü ofisiniz 8 metre kare ve diğer tek ofis ise 4 metre karedir.

G / Ç Kuralları

  • Giriş, stdin'den okunabilir ve çıktıyı stdout'a cevaplayabilir.

Veya

  • Girdi, bir işleve tek bir dize argümanı olabilir ve bu işlevin dönüş değeri cevap olabilir.

SSS

  • Tüm bina duvarlardan ve ofislerden oluşmaktadır.
  • Bina sadece bir kat
  • Girişte X olacağı garanti edilir, ancak boşluk olacağı garanti edilmez. 1x1'lik bir ofise sahip olabilirsiniz ve binanın geri kalanı duvarlardır (En büyük ofise sahipsiniz! Yaşasın!).

Diğer örnek

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

Burada 3 ofis var, güney ofisiniz dikdörtgen, kuzeybatı ofis bir üçgen (ish). Çıktı Yanlış olmalı.

Bu, en kısa kodu, mutlu golfünü yazmak için bir meydan okumadır !


Güzel sorun özelliği, ancak Xgirişte izin verilen maksimum sayıyı ekleyebilirsiniz . :)
Greg Hewgill

4
Sadece bir tane X var. X "siz" dir ve içinde bulunduğu odanın sizin olduğunu belirtir.
türbülanslı

Yanıtlar:


11

Ruby 2.0, 133 karakter

@Ventero ile bir işbirliği. Sözdizimi vurgulayıcısını kırmaya başladığında her zaman iyi bir işaret!

Bu özyinelemeli bir sel doldurma çözümüdür. STDIN'den okur ve STDOUT'ya çıktı verir:

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/]

İdeone üzerinde çalıştığını görün .


1
Çok hoş! Ben de uyarıları yeniden düzenleyerek iki daha fazla karakter kurtarabilir miyiz fbiraz: 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}. Ve eğer hatalıysam beni düzelt, ancak uzunluğu içeren ilk satırın $_gets$e;n=$_.to_i
içeride kalması

1
Ah, daha iyi. :) son düzenleme üzerinde bir daha gelişme: gets(p)yanı pbir şey ve döner yapar nilhiçbir argüman olmadan çağrılırsa.
Ventero

1
Aslında daha önce söylediklerimi geri alıyorum. İlk uyarlama düzenlemenizi kullanarak product, alıcıyı ltamamen ortadan kaldırmak için döndüren gerçeği kullanabiliriz : f=->*a{a.product([~n,-1,1,n+1]){|p,d|a|=[p+d]if$_[p+d]<?.}!=a ?f[*a]:a.size}- ne yazık ki !=boşluğu kaldırmak için lhs ve rhs ayarını değiştiremeyiz, aksi takdirde her iki taraf da değiştirilmemiş diziye işaret eder.
Ventero

1
Son bir gelişme: kötüye ile String#scanve ARGVbüyük oda bulmak, biraz kısaltılabilir: $_.scan(/ /){$*<<f[$.size]} p $ * maks <f [~ / x /] '.
Ventero

1
Maalesef yine Seni rahatsız eden için, ama aslında hiç atama inlining By :) ... başka gelişme bulundu niçine fböyle bir şeyle [~n=$_.to_i,...], daha sonra içine birinci ve üçüncü satırı birleştirebilirsiniz gets(p).scan(...134 karakter olmak üzere toplam.
Ventero

7

GolfScript (85 bayt)

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

Çevrimiçi demo

Bu üç bölümden oluşur:

  1. Başlangıç ​​pozisyonumu 0temsil etmek için bir duvarı N(toplam hücre sayısını) temsil etmek için bir 2D dizi üreten bir başlangıç ​​girişi dönüşümü ve birbirlerinin açık alanı için olanlar arasında belirgin bir sayı.

    n/(~.*:N:^;{{5%[0.^(:^N]=}/]}%
    
  2. Sel dolgusu.

    {{{.2$*!!{[\]$-1=.}*}*]}%zip}N*
    
  3. Son sayım. Bu, bir dizideki en yaygın eleman için uçta bir varyant kullanır ve buna karşı bastırıcı bir kravat kesici ekler N.

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

Gönderiniz için teşekkürler! Bir CJam çeviri: 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

Ungolfed baz versiyon

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
}

Ölçek

Firefox'ta Javascript konsolu

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

İkincisi 1de benim için verir (Firefox
30.0'da

@HackerCow Nedenini bilmiyorum, ancak test koduma göre & yapıştırırsanız, beyaz boşluklar sıkıştırılır. Her satır 10 karakter olmalıdır.
edc65

3

C #, 444 372 / (342 teşekkürler HackerCow) bayt

Oldukça zayıf puan ve partiye geç, ancak iş gibi görünüyor. En büyük tek ofise sahip olduğunuzda 1, yokken 0 olur. Henüz golf oynamaya çok karışmadım. Girdiden ayrık kümeler oluşturarak çalışır (ilk döngü), her kümenin boyutunu (ikinci döngü) söyleyerek ve ardından kümemin en büyük (üçüncü döngü) olup olmadığına bakar.

İki versiyon sağlanmıştır, biri derlenebilir bir programdır, tat komut satırından girdiyi kabul eder, diğeri girdi olarak bir dize bekleyen ve sonuç olarak bir int döndüren bir işlevdir (ve yalnızca ilk elden geçirilmiş bir kopyadır) - Herhangi bir cümle ya da benzeri bir maddeye ihtiyaç duymaz, onu herhangi bir yere koyabilir ve işe yarayabilir.

372 bayt program :

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

İşlev 342 bayt :

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;

Daha az golf oynadı:

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
Anladığım kadarıyla aslında çalışan bir program yazmak zorunda değilsiniz, bir fonksiyon yeterli. Daha önce tüm malzeme düşmesi Yani Mainfonksiyonu ile fonksiyonunu yerine, demek int f(string s)sen kullanabilirsiniz s.Split('\n')[0]yerine Console.ReadLine()iade ve 1ya 0. Bu size çok fazla kod kazandırmalıdır
Christoph Böhmwalder

@HackerCow teşekkürler, bu maddeyi tamamen kaçırdım! Bir sonraki düzenlememe bir fonksiyon sürümü koyacağım.
VisualMelon


2

Python 2 - 258 bayt

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

giriş için stdin kullanır

Not: ilk önce iftek bir boşlukla girintili, diğer girintili çizgiler ise tek bir sekme karakteri veya bir sekme ve boşluk kullanıyor.


1

J: 150 121 bayt

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

Düzenleme : idve compgülünç karmaşık ve yavaş. Artık haritayı 4 kez değiştirerek çalışıyor cut( 3x3 penceresiyle taramak yerine ;.).

Dizge olarak planı argüman olarak alır. Aşağıda açıklanmıştır:

    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 bayt

Vay. Uygulamadan çıktım.

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]

Bu bir fonksiyon cevabı, fakat global isim alanını kirletiyor. Bu kabul edilemez ise, 1 byte pahasına sabitlenebilir:

  • Satır 1'in başlangıcına bir boşluk ekle (+1)
  • Satır 2 ve 3'ün başındaki boşluğu sekme karakteriyle (+0) değiştirin
  • Satır 4'ü başına git (+0)

Çok uzun bir açıklama yazdım ama görünüşe göre düzgün bir şekilde kurtarmadı ve tekrar yapmam.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.