Sei nella stanza più grande?


29

introduzione

Di recente hai accettato un'offerta di lavoro presso una Pretty Good Software Company. Sei abbastanza contento delle dimensioni del tuo ufficio, ma hai l' ufficio più grande ? È un po 'difficile da dire guardando gli uffici dei tuoi colleghi quando ti fermi. L'unico modo per capirlo è esaminare i progetti per l'edificio ...

Il tuo compito

Scrivi un programma, uno script o una funzione che prenda una planimetria per il tuo edificio e indichi se il tuo ufficio è il più grande. La planimetria è di facile lettura perché l'edificio è un quadrato n per n .

L'input sarà composto da n + 1 \n righe delimitate. La prima riga avrà il numero n su di essa. Le prossime n righe saranno la planimetria dell'edificio. Un semplice input di esempio:

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

Le regole per la planimetria sono le seguenti:

  • .(ASCII 46) Sarà usato per rappresentare i muri. (Spazio [ASCII 32]) verrà utilizzato per rappresentare lo spazio aperto.
  • Sei rappresentato da un X(ASCII 88). Sei nel tuo ufficio.
  • La planimetria sarà composta da n righe, ognuna con n caratteri.
  • L'edificio è completamente circondato da mura su tutti i lati. Ciò implica che la seconda riga di input (la prima riga della planimetria) e l'ultima riga di input saranno tutte .s. Implica anche che il primo e l'ultimo carattere di ogni riga della planimetria saranno .s.
  • Le dimensioni di un ufficio sono definite come la somma degli spazi adiacenti (contigui spostandosi in 4 direzioni, N, S, E, W, senza attraversare un muro).
  • Ai fini delle dimensioni dell'ufficio, la X che ti rappresenta conta come (spazio aperto)
  • 4 <= n <= 80

Dovresti sapere se il tuo ufficio è strettamente più grande di tutti gli altri uffici. L'output può essere qualsiasi cosa che significhi inequivocabilmente Vero o Falso nel linguaggio di programmazione scelto e aderisca alle convenzioni standard di zero, null e vuoto che significa Falso. Vero implica che il tuo ufficio è strettamente il più grande.

Output di esempio per l'input sopra:

1

Perché il tuo ufficio è di 8 piedi quadrati e l'unico altro ufficio è di 4 piedi quadrati.

Linee guida I / O

  • L'input può essere letto da stdin e rispondere a stdout.

O

  • L'input può essere un singolo argomento stringa per una funzione e la risposta può essere il valore restituito di quella funzione.

FAQ

  • L'intero edificio è costituito da pareti e uffici.
  • L'edificio è solo un piano
  • È garantito che ci sia una X nell'input, ma non ci sono spazi garantiti. Potresti avere un ufficio 1x1 e il resto dell'edificio è costituito da muri (hai l'ufficio più grande! Evviva!).

Altro esempio

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

Qui ci sono 3 uffici, il tuo ufficio sud è rettangolare, l'ufficio nord-ovest è un triangolo (ish) e l'ufficio nord-est è stranamente deforme, ma più grande del tuo. L'output dovrebbe essere False.

Questa è una sfida per scrivere il codice più breve, felice ing!


Bella specifica del problema, ma è possibile aggiungere il numero massimo Xconsentito nell'input. :)
Greg Hewgill,

4
C'è solo una X. La X è "tu" e significa che la stanza in cui si trova è tua.
turbulencetoo

Risposte:


11

Ruby 2.0, 133 caratteri

Una collaborazione con @Ventero. Sempre un buon segno quando inizia a rompere l'evidenziatore della sintassi!

Questa è una soluzione di riempimento alluvione ricorsiva. Legge da STDIN e restituisce 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/]

Guardalo in esecuzione su Ideone .


1
Molto bella! Penso che puoi salvare altri due personaggi riorganizzando gli splat in fun po ': 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}. E correggimi se sbaglio, ma sembra che in realtà non abbia importanza se viene lasciata la prima riga contenente la lunghezza $_, il che ti permetterebbe di accorciare l'input analizzando agets$e;n=$_.to_i
Ventero

1
Ah, ancora meglio. :) Un ulteriore miglioramento rispetto alla tua ultima modifica:, gets(p)come pnon fa nulla e ritorna nilse chiamato senza alcun argomento.
Ventero,

1
In realtà, riprendo ciò che ho detto prima. Usando la tua disposizione iniziale splat, possiamo usare il fatto che productrestituisce il ricevitore per eliminarlo lcompletamente: f=->*a{a.product([~n,-1,1,n+1]){|p,d|a|=[p+d]if$_[p+d]<?.}!=a ?f[*a]:a.size}- sfortunatamente non possiamo cambiare lhs e rhs !=per rimuovere lo spazio, altrimenti entrambi i lati indicano l'array non modificato.
Ventero,

1
Un ultimo miglioramento: abusando String#scane ARGV, trovando la stanza più grande si può accorciare un po ': $_.scan(/ /){$*<<f[$.size]}; p $ *. Max <f [~ / X /] `
Ventero

1
Ci scusiamo per averti disturbato di nuovo, ma in realtà ho trovato un altro miglioramento ... :) Integrando il compito in nin fqualcosa del genere [~n=$_.to_i,...], puoi quindi combinare la prima e la terza riga in gets(p).scan(...per un totale di 134 caratteri.
Ventero,

7

GolfScript (85 byte)

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

Demo online

Questo ha tre sezioni:

  1. Una trasformazione di input iniziale che produce un array 2D usando 0per rappresentare un muro, N(il numero totale di celle) per rappresentare la mia posizione iniziale, e un numero distinto tra quelli per l'altro spazio aperto.

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

    {{{.2$*!!{[\]$-1=.}*}*]}%zip}N*
    
  3. Il conteggio finale. Questo utilizza una variante sulla punta per l' elemento più comune in un array , aggiungendo un tie-breaker che previene N.

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

grazie per la sua iscrizione! Traduzione A 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

Versione base non golfata

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
}

Test

Console Javascript in 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

Il secondo è anche 1per me (in Firefox 30.0)
Christoph Böhmwalder,

@HackerCow Non so perché, ma se esegui il cat & paste dal mio codice di test, gli spazi bianchi vengono compressi. Ogni riga dovrebbe essere di 10 caratteri.
edc65,

3

C #, 444 372 / (342 grazie a HackerCow) byte

Piuttosto scarso punteggio e in ritardo alla festa, ma sembra funzionare. Emette 1 quando hai il più grande ufficio singolo, 0 quando non lo hai. Non sono ancora stato molto intricato con il golf. Funziona costruendo set disgiunti dall'input (primo loop), calcolando la dimensione di ciascun set (secondo loop) e quindi cercando di vedere se il mio set è il più grande (terzo loop).

Sono fornite due versioni, una è un programma compilabile che accetta l'input dalla riga di comando, l'altra è solo una funzione che si aspetta una stringa come input e restituisce un int come risultato (ed è solo una copia rielaborata della prima) - non ha bisogno di alcuna clausola di utilizzo o simili, dovrebbe essere in grado di metterlo ovunque e funzionerà.

Programma 372 byte :

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

Funzione 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;

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

1
Per come l'ho capito, non devi scrivere un programma di lavoro, una funzione è sufficiente. Quindi, se lasci cadere tutte le cose prima della Mainfunzione e sostituisci la funzione con, supponi int f(string s)che potresti usare s.Split('\n')[0]invece di Console.ReadLine()e restituire 1o 0. Questo dovrebbe farti risparmiare un sacco di codice
Christoph Böhmwalder il

@HackerCow grazie, ho completamente perso quella clausola! Metterò una versione di funzione nella mia prossima modifica.
VisualMelon,


2

Python 2 - 258 byte

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 per l'input

Nota: prima ifviene indentato da un singolo spazio, altre linee rientrate utilizzano un singolo carattere di tabulazione o una scheda e uno spazio.


1

J: 150 121 byte

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

Modifica : ided comperano ridicolmente complicati e lenti. Ora funziona spostando la mappa 4 volte, invece di scansionarla con una finestra 3x3 usando cut( ;.).

Prende come argomento il progetto come stringa. Spiegato di seguito:

    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 byte

Wow. Sono fuori allenamento.

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]

Questa è una risposta alla funzione, ma inquina lo spazio dei nomi globale. Se ciò è inaccettabile, può essere risolto al costo di 1 byte:

  • Aggiungi uno spazio all'inizio della riga 1 (+1)
  • Sostituisci lo spazio all'inizio delle righe 2 e 3 con un carattere di tabulazione (+0)
  • Sposta la riga 4 all'inizio (+0)

Avevo scritto una lunga spiegazione, ma a quanto pare non è stato salvato correttamente e non lo farò di nuovo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.