Вы в самой большой комнате?

29

Введение

Вы недавно приняли предложение о работе в довольно хорошей компании по разработке программного обеспечения. Вы довольно довольны размером своего офиса, но у вас самый большой офис? Трудно сказать, просто заглядывая в офисы ваших коллег, когда вы заходите. Единственный способ понять это - изучить чертежи здания ...

Твое задание

Напишите программу, сценарий или функцию, которая принимает план здания для вашего здания и указывает, является ли ваш офис самым большим. План этажа легко читается, потому что здание представляет собой квадрат n на n .

Вход будет состоять из n + 1 \n -лимитированных строк. В первой строке будет номер n . Следующими n строками будет план этажа здания. Простой пример ввода:

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

Правила для плана этажа следующие:

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

Вы должны указать, является ли ваш офис строго больше всех остальных офисов. Выходными данными могут быть все, что однозначно означает Истина или Ложь в выбранном вами языке программирования и соответствует стандартным соглашениям, равным нулю, нулю и пустому значению Ложь. Правда подразумевает, что ваш офис строго самый большой.

Пример вывода для вышеуказанного ввода:

1

Потому что ваш офис 8 квадратных футов, а единственный другой офис - 4 квадратных фута.

Руководство по вводу / выводу

  • Входные данные могут быть прочитаны из стандартного ввода, а выходные данные - в стандартный вывод.

Или

  • Входные данные могут быть одним строковым аргументом функции, а answer - возвращаемым значением этой функции.

Вопросы-Ответы

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

Другой пример

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

Здесь есть 3 офиса, ваш южный офис прямоугольный, северо-западный офис - треугольник (иш), а северо-восточный офис странно деформирован, но больше, чем ваш. Вывод должен быть False.

Это задача написать самый короткий код, счастливый !

turbulencetoo
источник
Хорошая спецификация проблемы, но вы можете добавить максимально допустимое количество 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
Ventero
1
Ах, даже лучше. :) Еще одно улучшение по сравнению с вашим последним редактированием: gets(p)as 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 of !=для удаления пробела, так как в противном случае обе стороны указывают на неизмененный массив.
Вентеро
1
Одно из последних улучшений: злоупотребляя String#scanи ARGV, находя самую большую комнату, можно немного сократить: $_.scan(/ /){$*<<f[$.size]}; p $ *. Max <f [~ / X /] `
Ventero
1
Прошу прощения за то, что снова вас обидел, но на самом деле я обнаружил еще одно улучшение ... :) Вставив назначение nв fwith с помощью чего-то вроде [~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

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
}

Тест

Консоль 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
edc65
источник
Второй 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);
    }
}
VisualMelon
источник
1
Как я понял, вам не обязательно писать рабочую программу, достаточно функции. Поэтому, если вы отбросите все вещи перед Mainфункцией и замените функцию на, скажем, int f(string s)вы могли бы использовать s.Split('\n')[0]вместо Console.ReadLine()и return 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

использует ввод для ввода

Примечание: сначала ifотступ в один пробел, в других строках с отступом используется либо символ табуляции, либо табуляция и пробел.

6502
источник
1

J: 150 121 байт

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

Редактировать : idи compбыли смехотворно сложными и медленными. Теперь он работает, сдвигая карту 4 раза, вместо сканирования с помощью окна 3х3 с помощью 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
jpjacobs
источник
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)

У меня было написано целое длинное объяснение, но, видимо, оно не сохранилось должным образом, и я больше не буду это делать.

undergroundmonorail
источник