Ви в найбільшій кімнаті?


29

Вступ

Нещодавно ви прийняли пропозицію про роботу в компанії «Гарне програмне забезпечення». Ви досить задоволені розмірами свого офісу, але у вас найбільший офіс? Як би то не було важко розібратися з того, що просто заглянеш у кабінети колег, коли ти заїжджаєш. Єдиний спосіб зрозуміти це - вивчити креслення будівлі ...

Ваше завдання

Напишіть програму, сценарій або функцію, яка займає план поверху вашої будівлі та вказує, чи найбільше є ваш офіс. План поверху легко читати, оскільки будівля - це n на n квадратів.

Вхід буде складатися з n + 1 \n -делімітованих рядків. Перший рядок матиме на ньому число n . Наступними n рядками будуть план поверху будівлі. Простий приклад введення:

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

Правила плану поверху такі:

  • .(ASCII 46) буде використовуватися для зображення стін. (Простір [ASCII 32]) буде використовуватися для представлення відкритого простору.
  • Вас представляє X(ASCII 88). Ви в своєму кабінеті.
  • План плану буде складатися з n рядків, в кожному з яких по n символів.
  • Будівля повністю оточена стінами з усіх боків. Це означає, що другий рядок введення (перший рядок плану поверху) і останній рядок введення будуть усі .s. Це також означає, що перші та останні символи кожної лінії планування поверху будуть .s.
  • Розмір офісу визначається як сума сусідніх просторів (суміжне переміщення в 4 напрямках, N, S, E, W, не проходячи через стіну).
  • З метою розміру офісу X, який представляє вас, вважається (відкритий простір)
  • 4 <= n <= 80

Вам слід вивести, чи ваш офіс суворо більший, ніж усі інші офіси. Вихід може бути будь-яким, що однозначно означає True або False у вибраній вами мові програмування та дотримується стандартних умовних позначень нуля, нуля та порожнього, що означають False. Правда означає, що ваш офіс є строго найбільшим.

Вибірка вибору для вищевказаного входу:

1

Тому що ваш офіс - 8 квадратних футів, а єдиний інший офіс - 4 квадратних фути.

Вказівки щодо вводу / виводу

  • Вхід може бути прочитаний з stdin, а відповідь - на stdout.

Або

  • Вхід може бути аргументом одного рядка функції, а відповідь - поверненим значенням цієї функції.

FAQ

  • Вся будівля складається зі стін та офісів.
  • Будівля - лише один поверх
  • На вході гарантовано є X, але проміжки не гарантуються. У вас може бути офіс 1х1, а решта будівлі - стіни (у вас найбільший офіс! Ура!).

Інший приклад

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

Тут є три офіси, ваш південний офіс прямокутний, офіс на північному заході - це трикутник (іш), а офіс на північному сході дивно не змінюється, але більший за ваш. Вихід повинен бути помилковим.

Це завдання написати найкоротший код, щасливий !


Хороша специфікація проблеми, але ви можете додати максимальну кількість Xдозволених у вводі. :)
Грег Х'югілл

4
Є лише один X. X - це "ти" і означає, що кімната, в якій він знаходиться, - твоя.
турбулентність

Відповіді:


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
Дуже хороша! Я думаю , що ви можете зберегти більше двох символів перестановки Splats в 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
Вентеро,

1
Ах, ще краще. :) Ще одне поліпшення в порівнянні з вашою останньою редакцією:, gets(p)як pнічого не робить, і повертається, nilякщо викликається без аргументу.
Вентеро

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 !=на видалення простору, оскільки в іншому випадку обидві сторони вказують на немодифікований масив.
Вентеро

1
Останнє поліпшення: зловживаючи String#scanі ARGVзнаходячи найбільшу кімнату, можна трохи скоротити: $_.scan(/ /){$*<<f[$.size]}; p $ *. Max <f [~ / X /] `
Вентеро,

1
Вибачте за те, що вас знову помилили, але я фактично знайшов ще одне вдосконалення ... :) Вставивши завдання на nв fщось подібне [~n=$_.to_i,...], ви можете потім об'єднати перший і третій рядки в gets(p).scan(...загальну кількість 134 символів.
Вентеро

7

GolfScript (85 байт)

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

Демонстрація в Інтернеті

Це три розділи:

  1. Початкове вхідне перетворення, яке створює двовимірний масив, використовуючи 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)
Крістоф Бьомвальдер

@HackerCow Я не знаю, чому, але якщо ви вводите і вставляєте з мого тестового коду, білі пробіли стискаються. Кожен рядок повинен бути 10 символів.
edc65

3

C #, 444 372 / (342 спасибі HackerCow) байтів

Досить поганий бал та запізнення на вечірку, але, здається, працює. Виходи 1, коли у вас є найбільший офіс, 0 - у вас немає. Я ще не дуже заплутався з гольфом. Працює, створюючи роз'єднані набори з вхідних даних (перший цикл), підраховуючи розмір кожного набору (другий цикл), а потім дивлячись, чи є мій набір найбільшим (третій цикл).

Надано дві версії, одна - це компілювана програма, яка приймає вхід з командного рядка, інша - це лише функція, яка очікує рядок як вхідний і повертає int як результат (і є лише переробленою копією першої) - йому не потрібні жодні користування пунктами тощо, вони повинні вміти розміщувати його куди завгодно, і він спрацює.

Програма 372байт :

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()і повернути 1або 0. Це має заощадити багато коду
Крістоф Бьомвальдер

@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=&

Спробуйте тут


Дякуємо за ваше подання Але ваша програма кидає виняток із цим вкладом: pastebin.com/v989KhWq
jimmy23013

@ user23013 виправлено.
Оптимізатор

Спробуйте такі: 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)

У мене було виписано ціле довге пояснення, але, мабуть, воно не врятувало належним чином, і я не роблю цього знову lmao

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.