¿Estás en la habitación más grande?

29

Introducción

Recientemente ha aceptado una oferta de trabajo en Pretty Good Software Company. Estás bastante contento con el tamaño de tu oficina, pero ¿tienes la oficina más grande ? Es un poco difícil de distinguir simplemente mirando las oficinas de tus compañeros de trabajo cuando pasas por aquí. La única forma de resolver esto es examinar los planos del edificio ...

Tu tarea

Escriba un programa, script o función que tome un plano de planta para su edificio e indique si su oficina es la más grande. El plano de planta es fácil de leer porque el edificio es un cuadrado de n por n .

La entrada consistirá en n + 1 \n líneas delimitadas. La primera línea tendrá el número n . Las siguientes n líneas serán el plano del edificio. Un ejemplo de entrada simple:

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

Las reglas para el plano son las siguientes:

  • .(ASCII 46) Se utilizará para representar paredes. (Espacio [ASCII 32]) se utilizará para representar el espacio abierto.
  • Estás representado por un X(ASCII 88). Estas en tu oficina
  • El plano será de n líneas, cada una con n caracteres.
  • El edificio está totalmente rodeado de paredes por todos lados. Esto implica que la segunda línea de entrada (la primera línea del plano de planta) y la última línea de entrada serán todas .s. También implica que el primer y último carácter de cada línea del plano será .s.
  • El tamaño de una oficina se define como la suma de espacios adyacentes (contiguos moviéndose en 4 direcciones, N, S, E, W, sin atravesar una pared).
  • Para el tamaño de la oficina, la X que lo representa cuenta como un (espacio abierto)
  • 4 <= n <= 80

Debe indicar si su oficina es estrictamente más grande que todas las demás. La salida puede ser cualquier cosa que signifique inequívocamente Verdadero o Falso en el lenguaje de programación de su elección y se adhiera a las convenciones estándar de cero, nulo y vacío que significa Falso. Verdadero implica que su oficina es estrictamente la más grande.

Salida de muestra para la entrada anterior:

1

Porque su oficina es de 8 pies cuadrados, y la única otra oficina es de 4 pies cuadrados.

Pautas de E / S

  • La entrada puede leerse desde stdin, y responder la salida a stdout.

O

  • La entrada puede ser un argumento de cadena única para una función, y la respuesta será el valor de retorno de esa función.

Preguntas más frecuentes

  • Todo el edificio consta de muros y oficinas.
  • El edificio es de una sola planta.
  • Se garantiza que haya una X en la entrada, pero no se garantiza que haya ningún espacio. Podrías tener una oficina 1x1 y el resto del edificio son paredes (¡tienes la oficina más grande! ¡Hurra!).

Otro ejemplo

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

Aquí hay 3 oficinas, su oficina sur es rectangular, la oficina noroeste es un triángulo (ish) y la oficina noreste está extrañamente deformada, pero es más grande que la suya. La salida debe ser False.

¡Es un desafío escribir el código más corto, feliz !

turbulencia también
fuente
Buena especificación del problema, pero puede agregar el número máximo Xpermitido en la entrada. :)
Greg Hewgill
44
Solo hay una X. La X es "usted" y significa que la habitación en la que se encuentra es suya.
turbulencetoo

Respuestas:

11

Ruby 2.0, 133 caracteres

Una colaboración con @Ventero. ¡Siempre es una buena señal cuando comienza a romper el resaltador de sintaxis!

Esta es una solución recursiva de relleno de inundación. Lecturas de STDIN y salidas a 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/]

Ver que se ejecuta en Ideone .

Paul Prestidge
fuente
1
¡Muy agradable! Creo que se puede salvar a dos personajes más de la reordenación de los símbolos de en fun poco: 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}. Y me corrija si estoy equivocado, pero parece que en realidad no importa si la primera línea que contiene la longitud se deja en $_, lo que permitirá acortar el análisis de entrada agets$e;n=$_.to_i
Ventero
1
Ah, incluso mejor. :) Una mejora más sobre su última edición: gets(p)como pno hace nada y devuelve nilsi se llama sin argumento.
Ventero
1
En realidad, retiro lo que dije antes. Usando su disposición inicial de splat, podemos usar el hecho de que productdevuelve el receptor para eliminar por lcompleto: f=->*a{a.product([~n,-1,1,n+1]){|p,d|a|=[p+d]if$_[p+d]<?.}!=a ?f[*a]:a.size}- desafortunadamente no podemos cambiar los valores de lhs y rhs !=para eliminar el espacio, ya que de lo contrario ambos lados apuntan a la matriz no modificada.
Ventero
1
Una última mejora: al abusar String#scany ARGVencontrar la habitación más grande se puede acortar un poco: $_.scan(/ /){$*<<f[$.size]}; p $ *. Max <f [~ / X /] `
Ventero
1
Perdón por molestarte nuevamente, pero en realidad encontré otra mejora ... :) Al incluir la tarea nen falgo así [~n=$_.to_i,...], puedes combinar la primera y la tercera línea gets(p).scan(...para obtener un total de 134 caracteres.
Ventero
7

GolfScript (85 bytes)

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

Demostración en línea

Esto tiene tres secciones:

  1. Una transformación de entrada inicial que produce una matriz 2D usando 0para representar un muro, N(el número total de celdas) para representar mi posición inicial, y un número distinto entre ellos para cada uno de los espacios abiertos.

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

    {{{.2$*!!{[\]$-1=.}*}*]}%zip}N*
    
  3. El conteo final. Esto utiliza una variante en la punta para el elemento más común en una matriz , agregando un interruptor de desempate contra el cual se influye N.

    []*0-:A{.N=A@-,2*+}$0=N=
    
Peter Taylor
fuente
¡Gracias por tu envío! Una traducció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

Versión base sin golf

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
}

Prueba

Consola Javascript en 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
fuente
El segundo da 1para mí también (en Firefox 30.0)
Christoph Böhmwalder
@HackerCow No sé por qué, pero si eliminas y pegas desde mi código de prueba, los espacios en blanco se comprimen. Cada línea debe tener 10 caracteres.
edc65
3

C #, 444 372 / (342 gracias HackerCow) bytes

Puntaje bastante pobre y tarde a la fiesta, pero parece funcionar. Salidas 1 cuando tiene la oficina más grande, 0 cuando no la tiene. Todavía no he sido muy intrincado con el golf. Funciona construyendo conjuntos disjuntos a partir de la entrada (primer bucle), calculando el tamaño de cada conjunto (segundo bucle) y luego mirando para ver si mi conjunto es el más grande (tercer bucle).

Se proporcionan dos versiones, una es un programa compilable que acepta la entrada desde la línea de comandos, la otra es solo una función que espera una cadena como entrada y devuelve un int como resultado (y es solo una copia reelaborada de la primera): no necesita cláusulas de uso o similares, debería poder colocarlo en cualquier lugar y funcionará.

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

Función 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;

Menos golfizado:

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
fuente
1
Según tengo entendido, no es necesario escribir un programa de trabajo, una función es suficiente. Entonces, si suelta todas las cosas antes de la Mainfunción y la reemplaza con, digamos int f(string s)que podría usar en s.Split('\n')[0]lugar de Console.ReadLine()y regresar 1o 0. Esto debería ahorrarle mucho código
Christoph Böhmwalder
@HackerCow gracias, ¡me perdí completamente esa cláusula! Pondré una versión de función en mi próxima edición.
VisualMelon
2

CJam, 106 bytes

Un enfoque diferente para el relleno de inundaciones. Aunque, lo hace más largo ...

liqN-'Xs0aer\_:L*{_A=' ={[AAL-A(]1$f=$:D1=Sc<{D2<(aer}*D0=_' ={T):T}@?A\t}*}fAT),\f{\a/,}_$W%_2<~>@@0=#0=&

Pruébalo aquí

Optimizador
fuente
Gracias por tu presentación. Pero su programa arroja una excepción con esta entrada: pastebin.com/v989KhWq
jimmy23013
@ user23013 fijo.
Optimizador
Pruebe estos: pastebin.com/WyRESLWE
jimmy23013
2

Python 2 - 258 bytes

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

usa stdin para entrada

Nota: primero ifestá sangrado por un solo espacio, otras líneas sangradas están usando una sola pestaña char o una pestaña y un espacio.

6502
fuente
1

J: 150 121 bytes

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

Editar : idy compfueron ridículamente complicados y lentos. Ahora funciona cambiando el mapa 4 veces, en lugar de escanearlo con una ventana de 3x3 usando cut( ;.).

Toma como argumento el plano como cadena. Explicado a continuación:

    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
fuente
0

Python 2 - 378 bytes

Guau. Estoy fuera de práctica.

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]

Esta es una respuesta de función, pero contamina el espacio de nombres global. Si esto es inaceptable, se puede arreglar al costo de 1 byte:

  • Agregue un espacio al comienzo de la línea 1 (+1)
  • Reemplace el espacio al comienzo de las líneas 2 y 3 con un carácter de tabulación (+0)
  • Mover la línea 4 al principio (+0)

Tenía toda una larga explicación escrita, pero aparentemente no se guardó correctamente y no lo volveré a hacer lmao

metro subterráneo
fuente