Êtes-vous dans la plus grande salle?

29

introduction

Vous avez récemment accepté une offre d'emploi dans une très bonne société de logiciels. Vous êtes plutôt satisfait de la taille de votre bureau, mais avez-vous le plus grand bureau? C'est un peu difficile à dire de simplement regarder les bureaux de vos collègues lorsque vous vous arrêtez. La seule façon de comprendre cela est d'examiner les plans du bâtiment ...

Ta tâche

Écrivez un programme, un script ou une fonction qui prend un plan d'étage pour votre bâtiment et indique si votre bureau est le plus grand. Le plan d'étage est facile à lire car le bâtiment est un carré n par n .

L'entrée consistera en n + 1 \n lignes délimitées. La première ligne aura le numéro n dessus. Les n lignes suivantes seront le plan d'étage du bâtiment. Un exemple simple d'entrée:

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

Les règles du plan d'étage sont les suivantes:

  • .(ASCII 46) Sera utilisé pour représenter les murs. (Espace [ASCII 32]) sera utilisé pour représenter un espace ouvert.
  • Vous êtes représenté par un X(ASCII 88). Vous êtes dans votre bureau.
  • Le plan d' étage sera n lignes, chacun avec n caractères.
  • Le bâtiment est totalement entouré de murs de tous les côtés. Cela implique que la 2e ligne d'entrée (la première ligne du plan d'étage) et la dernière ligne d'entrée seront toutes .s. Cela implique également que les premier et dernier caractères de chaque ligne de plan d'étage seront .s.
  • Une taille de bureau est définie comme la somme des espaces adjacents (contigus en se déplaçant dans 4 directions, N, S, E, W, sans passer par un mur).
  • Aux fins de la taille du bureau, le X qui vous représente compte comme (espace ouvert)
  • 4 <= n <= 80

Vous devez indiquer si votre bureau est strictement plus grand que tous les autres bureaux. La sortie peut être tout ce qui signifie sans ambiguïté True ou False dans le langage de programmation de votre choix et adhère aux conventions standard de zéro, null et vide signifiant False. Vrai implique que votre bureau est strictement le plus grand.

Exemple de sortie pour l'entrée ci-dessus:

1

Parce que votre bureau est de 8 pieds carrés, et le seul autre bureau est de 4 pieds carrés.

Consignes d'E / S

  • L'entrée peut être lue à partir de stdin et répondre à stdout.

Ou

  • L'entrée peut être un argument de chaîne unique pour une fonction, et la réponse doit être la valeur de retour de cette fonction.

FAQ

  • L'ensemble du bâtiment se compose de murs et de bureaux.
  • Le bâtiment est d'un seul étage
  • Il est garanti qu'il y ait un X dans l'entrée, mais il n'y a pas de garantie qu'il y ait des espaces. Vous pourriez avoir un bureau 1x1 et le reste du bâtiment est des murs (vous avez le plus grand bureau! Hourra!).

Autre exemple

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

Ici, il y a 3 bureaux, votre bureau sud est rectangulaire, le bureau nord-ouest est un triangle (ish) et le bureau nord-est est étrangement déformé, mais plus grand que le vôtre. La sortie doit être False.

C'est un défi d'écrire le code le plus court, joyeux !

turbulencetoo
la source
Belle spécification de problème, mais vous pouvez ajouter le nombre maximal de X autorisé dans l'entrée. :)
Greg Hewgill
4
Il n'y a qu'un seul X. Le X est "vous" et signifie que la pièce dans laquelle il se trouve est la vôtre.
turbulencetoo

Réponses:

11

Ruby 2.0, 133 caractères

Une collaboration avec @Ventero. Toujours un bon signe quand il commence à casser le surligneur de syntaxe!

Il s'agit d'une solution de remplissage inondable récursive. Lit depuis STDIN et sort vers 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/]

Le voir fonctionnement sur Ideone .

Paul Prestidge
la source
1
Très agréable! Je pense que vous pouvez enregistrer deux caractères en réorganisant les flocs dans fun peu: 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}. Et corrigez-moi si je me trompe, mais il semble que cela n'ait pas vraiment d'importance si la première ligne contenant la longueur est laissée $_gets$e;n=$_.to_i
dedans
1
Ah, encore mieux. :) Encore une amélioration par rapport à votre dernière édition:, tout gets(p)comme prien et retourne nils'il est appelé sans argument.
Ventero
1
En fait, je reprends ce que j'ai dit plus tôt. En utilisant votre arrangement initial de splat, nous pouvons utiliser le fait que productle récepteur retourne pour éliminer lcomplètement: f=->*a{a.product([~n,-1,1,n+1]){|p,d|a|=[p+d]if$_[p+d]<?.}!=a ?f[*a]:a.size}- malheureusement nous ne pouvons pas changer les lhs et rhs de !=pour supprimer l'espace, sinon les deux côtés pointent vers le tableau non modifié.
Ventero
1
Une dernière amélioration: en abusant String#scanet ARGVen trouvant la plus grande salle peut être un peu raccourcie: $_.scan(/ /){$*<<f[$.size]}; p $ *. Max <f [~ / X /] `
Ventero
1
Désolé de vous avoir encore mis sur écoute, mais j'ai en fait trouvé une autre amélioration ... :) En insérant l'affectation à ndans favec quelque chose comme [~n=$_.to_i,...], vous pouvez ensuite combiner la première et la troisième ligne dans gets(p).scan(...pour un total de 134 caractères.
Ventero
7

GolfScript (85 octets)

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

Démo en ligne

Cela comprend trois sections:

  1. Une transformation d'entrée initiale qui produit un tableau 2D en utilisant 0pour représenter un mur, N(le nombre total de cellules) pour représenter ma position de départ, et un nombre distinct entre ceux pour l'autre espace ouvert.

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

    {{{.2$*!!{[\]$-1=.}*}*]}%zip}N*
    
  3. Le décompte final. Cela utilise une variante sur la pointe pour l'élément le plus courant dans un tableau , en ajoutant un bris d'égalité contre lequel N.

    []*0-:A{.N=A@-,2*+}$0=N=
    
Peter Taylor
la source
Merci pour votre soumission! Une traduction 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

Version de base non golfée

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
}

Tester

Console Javascript dans 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
la source
Le second 1me donne aussi (dans Firefox 30.0)
Christoph Böhmwalder
@HackerCow Je ne sais pas pourquoi, mais si vous copiez et collez à partir de mon code de test, les espaces blancs sont compressés. Chaque ligne doit contenir 10 caractères.
edc65
3

C #, 444 372 / (342 merci HackerCow) octets

Score plutôt médiocre et en retard à la fête, mais semble fonctionner. Sorties 1 lorsque vous avez le plus grand bureau unique, 0 lorsque vous n'en avez pas. Je n'ai pas encore été très compliqué avec le golf. Fonctionne en créant des ensembles disjoints à partir de l'entrée (première boucle), en comptant la taille de chaque ensemble (deuxième boucle) et en cherchant ensuite si mon ensemble est le plus grand (troisième boucle).

Deux versions sont fournies, l'une est un programme compilable qui accepte l'entrée de la ligne de commande, l'autre est juste une fonction qui attend une chaîne en entrée et renvoie un int comme résultat (et n'est qu'une copie retravaillée de la première) - il n'a besoin d'aucune clause using ou similaire, devrait pouvoir le mettre n'importe où et cela fonctionnera.

Programme 372 octets :

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

Fonction 342 octets :

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;

Moins golfé:

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
la source
1
D'après ce que j'ai compris, vous n'avez pas besoin d'écrire un programme de travail, une fonction suffit. Donc, si vous déposez tous les éléments avant la Mainfonction et remplacez la fonction par, dites que int f(string s)vous pouvez utiliser à la s.Split('\n')[0]place de Console.ReadLine()et retourner 1ou 0. Cela devrait vous faire économiser beaucoup de code
Christoph Böhmwalder
@HackerCow merci, j'ai complètement raté cette clause! Je mettrai une version de fonction dans ma prochaine édition.
VisualMelon
2

CJam, 106 octets

Une approche différente du remplissage des inondations. Bien, le rend plus long ...

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

Essayez-le ici

Optimiseur
la source
Merci pour votre soumission. Mais votre programme lève une exception avec cette entrée: pastebin.com/v989KhWq
jimmy23013
@ user23013 fixe.
Optimizer
Essayez-les: pastebin.com/WyRESLWE
jimmy23013
2

Python 2 - 258 octets

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

utilise stdin pour l'entrée

Remarque: le premier ifest mis en retrait par un seul espace, les autres lignes en retrait utilisent soit un caractère de tabulation unique, soit un onglet et un espace.

6502
la source
1

J: 150 121 octets

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

Edit : idet compétaient ridiculement compliqués et lents. Maintenant, cela fonctionne en déplaçant la carte 4 fois, au lieu de la numériser avec une fenêtre 3x3 en utilisant cut( ;.).

Prend comme argument le plan comme chaîne. Expliqué ci-dessous:

    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
la source
0

Python 2 - 378 octets

Sensationnel. Je suis hors de pratique.

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]

C'est une réponse de fonction, mais elle pollue l'espace de noms global. Si cela est inacceptable, il peut être corrigé au prix d'un octet:

  • Ajoutez un espace au début de la ligne 1 (+1)
  • Remplacez l'espace au début des lignes 2 et 3 par un caractère de tabulation (+0)
  • Déplacer la ligne 4 au début (+0)

J'ai eu toute une longue explication écrite, mais apparemment, cela n'a pas enregistré correctement et je ne recommence pas lmao

métro monorail
la source