1P5: caselle nidificate


53

Questo compito fa parte del primo periodico Premier Programming Puzzle Push .

Ottieni una gerarchia di elementi nel seguente formato:

2
Hat
1
Gloves

che devono essere messi in scatole, in questo modo:

.------------.
| Hat        |
| .--------. |
| | Gloves | |
| '--------' |
'------------'

Nel formato di input i numeri iniziano una casella con tutti gli elementi specificati dal numero. La prima scatola contiene due oggetti (il Cappello e la scatola che contiene i Guanti), la seconda contiene un solo oggetto: i guanti.

Come si può vedere, anche le scatole possono vivere all'interno delle scatole. E sono sempre arrotondati ... in un certo senso (gli angoli appuntiti sono un pericolo per la ferita e non lo vorremmo).

Di seguito ci sono i dettagli sgradevoli per coloro che vogliono utilizzare ogni piccolo margine di manovra fornito dalle specifiche. Intendiamoci, non leggere le specifiche non è una scusa per presentare soluzioni sbagliate. C'è uno script di test e alcuni casi di test alla fine.


specificazione

  • Le scatole sono costruite con i seguenti caratteri:

    • | (U + 007C) viene utilizzato per costruire i bordi verticali.
    • - (U + 002D) viene utilizzato per costruire i bordi orizzontali.
    • ' (U + 0027) sono gli angoli inferiori rotondi.
    • . (U + 002E) sono gli angoli superiori rotondi.

    Una scatola quindi appare così:

    .--.
    |  |
    '--'
    

    Si noti che, sebbene Unicode abbia anche angoli arrotondati e caratteri di disegno a scatola adeguati, questa attività è solo in ASCII. Per quanto amo Unicode, mi rendo conto che ci sono lingue e ambienti che non sono arrivati ​​nel secondo all'ultimo decennio.

  • Le caselle possono contenere una sequenza di elementi che sono testo o altri elementi. I singoli elementi in una casella vengono visualizzati dall'alto verso il basso. La sequenza A, B, C viene quindi visualizzata come segue:

    .---.
    | A |
    | B |
    | C |
    '---'
    

    Questo ovviamente si applica anche alle caselle nidificate, che sono un elemento proprio come il testo. Quindi la sequenza A, B, Riquadro (C, Riquadro (D, E)), F verrebbe visualizzato come segue:

    .-----------.
    | A         |
    | B         |
    | .-------. |
    | | C     | |
    | | .---. | |
    | | | D | | |
    | | | E | | |
    | | '---' | |
    | '-------' |
    | F         |
    '-----------'
    
  • Le caselle adattano le loro dimensioni al contenuto e le caselle nidificate si estendono sempre alle dimensioni del loro genitore. C'è sempre uno spazio prima e dopo il contenuto, in modo che né il testo né i riquadri nidificati siano troppo vicini al bordo del riquadro esterno. In breve, quanto segue è sbagliato:

    .---.
    |Box|
    '---'
    

    E il seguente è corretto:

    .-----.
    | Box |
    '-----'
    

    Sembra anche molto più bello :-)

  • Gli elementi di testo (vedi input sotto) devono essere riprodotti esattamente.

  • C'è sempre una sola casella di livello superiore (vedi XML). Tuttavia, una casella può contenere diverse altre caselle.

Ingresso

  • L'input è dato su input standard; per test più facili probabilmente reindirizzati da un file.

  • L'input viene dato in linea, con ogni riga che rappresenta un elemento di testo da inserire nella casella corrente o l'apertura di una nuova casella.

  • Ogni riga è terminata da un'interruzione di riga.

  • Gli elementi di testo sono contrassegnati da una riga che non è composta da un numero (vedi sotto). Il testo utilizza caratteri alfabetici, lo spazio e la punteggiatura ( .,-'"?!()). Il testo non inizierà o finirà con uno spazio e avrà sempre almeno un carattere.

  • Una casella inizia con una singola riga con un numero al suo interno. Il numero indica la dimensione della casella, ovvero il numero dei seguenti elementi che vengono inseriti:

    2
    A
    B
    

    restituisce una casella con due elementi di testo:

    .---.
    | A |
    | B |
    '---'
    

    Una scatola conterrà sempre almeno un oggetto.

  • La fine delle caselle non è esplicitamente contrassegnata da una linea; invece le caselle vengono implicitamente chiuse dopo che il numero specificato di elementi viene inserito in esse.

  • Una scatola è sempre solo un singolo oggetto, indipendentemente da quanti oggetti ci siano. Per esempio

    3
    A
    4
    a
    b
    c
    d
    B
    

    produrrà una scatola con tre oggetti, il secondo dei quali è un'altra scatola con quattro oggetti.

    La nidificazione inoltre non influisce sul fatto che una scatola è solo un singolo elemento.

limiti

  • Il livello massimo di annidamento è cinque . Cioè ci sono al massimo cinque scatole l'una dentro l'altra. Questo include quello più esterno.

  • C'è un massimo di dieci articoli per scatola.

  • Gli elementi di testo hanno una lunghezza massima di 100 caratteri.

Produzione

  • L'output è la casella di rendering che include tutti gli elementi contenenti e nidificati in base alle regole descritte sopra.
  • L'output deve essere fornito su output standard e deve corrispondere esattamente. Non sono consentiti spazi bianchi iniziali o finali.
  • Ogni riga deve essere terminata con un'interruzione di riga, inclusa l'ultima.

Condizioni vincenti

  • Vince il codice più breve (ovvero ottiene la risposta accettata).

Esempio di input 1

3
This is some text!
Oh, more text?
Just text for now, as this is a trivial example.

Uscita campione 1

.--------------------------------------------------.
| This is some text!                               |
| Oh, more text?                                   |
| Just text for now, as this is a trivial example. |
'--------------------------------------------------'

Esempio di input 2

4
Extreme
nesting
3
of
boxes
4
might
lead
to
2
interesting
1
visuals.
Indeed!

Uscita campione 2

.--------------------------.
| Extreme                  |
| nesting                  |
| .----------------------. |
| | of                   | |
| | boxes                | |
| | .------------------. | |
| | | might            | | |
| | | lead             | | |
| | | to               | | |
| | | .--------------. | | |
| | | | interesting  | | | |
| | | | .----------. | | | |
| | | | | visuals. | | | | |
| | | | '----------' | | | |
| | | '--------------' | | |
| | '------------------' | |
| '----------------------' |
| Indeed!                  |
'--------------------------'

Esempio di input 3

1
1
1
1
1
Extreme nesting Part Two

Uscita campione 3

.------------------------------------------.
| .--------------------------------------. |
| | .----------------------------------. | |
| | | .------------------------------. | | |
| | | | .--------------------------. | | | |
| | | | | Extreme nesting Part Two | | | | |
| | | | '--------------------------' | | | |
| | | '------------------------------' | | |
| | '----------------------------------' | |
| '--------------------------------------' |
'------------------------------------------'

Esempio di input 4

3
Foo
2
Bar
Baz
2
Gak
1
Another foo?

Uscita campione 4

.----------------------.
| Foo                  |
| .------------------. |
| | Bar              | |
| | Baz              | |
| '------------------' |
| .------------------. |
| | Gak              | |
| | .--------------. | |
| | | Another foo? | | |
| | '--------------' | |
| '------------------' |
'----------------------'

Test script

Dal momento che ottenere i dettagli giusti può essere difficile a volte ( noi e Ventero ) abbiamo preparato uno script di test con cui è possibile eseguire la soluzione per verificare se è corretta. E 'disponibile sia come script di PowerShell e script bash . Invocazione è: <test-script> <program invocation>.

AGGIORNAMENTO: gli script di test sono stati aggiornati; c'erano diversi casi di test che non rispettavano i limiti da me definiti. Lo script di test di PowerShell non ha utilizzato il confronto con distinzione tra maiuscole e minuscole per verificare il risultato. Spero che ora vada tutto bene. Il numero di casi di test è stato ridotto a 156, sebbene l'ultimo ora sia abbastanza ... grande.

AGGIORNAMENTO 2: ho caricato il mio generatore di test case . Scritto in C # , destinato al runtime .NET 2. Funziona su Mono. Può aiutare le persone a testare la loro implementazione. Come caso peggiore definitivo, dati i limiti dell'attività, puoi provare:

nb.exe 1 10 10 5 100 100 | my invocation

che genererà solo riquadri fino al livello più interno e utilizzerà sia il numero massimo di elementi per riquadro sia la lunghezza massima degli elementi di testo. Non ho incluso questo caso di test nello script di test, poiché è piuttosto grande e l'output è ancora più grande.

AGGIORNAMENTO 3: ho aggiornato lo script di test di PowerShell che era incline a generare errori a seconda di come erano terminate le righe nello script e quali terminazioni di riga stampavano la soluzione. Ora dovrebbe essere agnostico per entrambi. Scusami ancora per la confusione.


Dici che le scatole dovrebbero adattare le loro dimensioni al loro contenuto. Tuttavia, nell'ultimo esempio, la prima casella interna regola le dimensioni della casella esterna. Quindi, in che modo la scatola nidificata ottiene le loro dimensioni?
Juan,

@Juan: grazie per averlo colto. Incredibile che scivoli come quelli che accadono ancora. A cura di :-)
Joey,

1
@Joey Un vecchio ma un buono. Spero che possa ispirare alcuni dei nostri nuovi utenti a scrivere domande valide e ben specificate. :-)
Gareth

@Gareth, dovrei assolutamente cercare di trovare il tempo per scriverne di più. Ma una domanda ben specificata, casi di test, implementazione di riferimento e cose (cose che considero essenziali per una competizione, ma che l'opinione non è condivisa da molti;)) richiedono tempo. È stato molto più semplice in uni: D
Joey

Risposte:


2

GolfScript, 125 caratteri

n/):B;[(~{[B"."+"""-"]B"| "+:B;@@{(.10,`-{[B\" "]\}{~A}if}*B[2>:B"'"+"""-"]\}:A~;].{~;1$++,}%$-1=:§;{~§3$.+3$+,-*+1$-1%++}%n*

Utilizzando un approccio simile alla soluzione di Keith .


26

Python, 204 caratteri

def P(n):x=raw_input();return eval('[(n+".","","-")]'+'+P(n+"| ")'*int(x))+[(n+"'",'','-')]if'0'<x<':'else[(n,x,' ')]
r=P('')
for q,t,f in r:print q+t+f*(max(len(2*x+y)for x,y,a in r)-len(2*q+t))+q[::-1]

Prestituisce un elenco di triple, ognuna delle quali è un prefisso / suffisso di riga (il suffisso è il contrario del prefisso), del testo di una riga e un carattere di riempimento di riga. Dopo aver calcolato tutte le triple, vengono stampate usando il giusto numero di caratteri di riempimento per rendere tutte le linee della stessa lunghezza.

Versione non golfata:

def get_lines(prefix):
  line=raw_input()
  result=[]
  if line.isdigit():
    result.append((prefix+'.', '', '-'))
    for i in xrange(int(line)):
      result += get_lines(prefix + '| ')
    result.append((prefix+"'", '', '-'))
  else:
    result.append((prefix, line, ' '))
  return result
lines=get_lines('')
width=max(2*len(prefix)+len(text) for prefix,text,fill in lines)
for prefix,text,fill in lines:
  print prefix+text+fill*(width-2*len(prefix)-len(text))+prefix[::-1]

Whoa, è stato veloce. E un'idea interessante con Plì.
Joey,

Caspita. Questo è interessante, puoi pubblicare la versione non giocata? Mi piacerebbe capire come funziona il bit eval. Heh, la mia soluzione non pitone di Python è di oltre 1500 caratteri :( Sebbene io abbia un approccio totalmente diverso (e inefficiente).
Casey,

@Casey: eval è solo una scorciatoia da golf per un loop, non è fondamentale. Pubblicherò una versione non giocata tra un secondo ...
Keith Randall,

13

Ruby 1.9, 174 caratteri

r=->l{$*<<(l*2+i=gets.chop).size;/\d/?eval('[l+?.,p=?-,p,'+'*r["| "+l],'*i.to_i+"l+?',p,p]"):[l,i,?\s]}
r[""].each_slice(3){|a,b,c|puts a+b+c*($*.max-(a*2+b).size)+a.reverse}

Un po 'simile alla soluzione di Keith .


6

APL (78)

{∧/⎕D∊⍨I←⍞:{∆,('-'⍪⍵⍪'-'),∆←'.|'''/⍨1(⊃⍴⍵)1}⍕⍪/{⍵↑[2]⍨⌈/⊃∘⌽∘⍴¨∆}¨∆←∇¨⍳⍎I⋄⍉⍪I}⍬

5
che cosa non
dico

Non riesco a farlo funzionare su tio.run per testare la soluzione. Altrimenti cambierei anche la risposta accettata.
Joey,

5

Python - 355 314 259 caratteri

w=0
def p(n,l):
 global w;f=[(l-1,0)]
 for k in' '*n:
  i=raw_input()
  try:f+=p(int(i),l+1)
  except:f+=[(l,i)];w=max(w,4*l+len(i))
 return f+[(l-1,1)]
for l,s in p(input(),1):p=w-4*l-2;print'| '*l+(".'"[s]+'-'*p+".'"[s]if s<2 else s+' '*(p+2-len(s)))+' |'*l

quasi una riduzione di 100 caratteri, buon lavoro.
Casey,

5

Ruby 1.9, 229 228 226 223 222

g=->n{(1..n).map{g[Integer l=gets.chop]rescue l}}
w=->b{b.bytesize rescue b.map{|e|w[e]}.max+4}
p=->b,c{r=c-2
[?.+?-*r+?.,*b.map{|i|p[i,c-4]}.flatten.map{|k|"| #{k} |"},?'+?-*r+?']rescue[b.ljust(c)]}
puts p[b=g[1][0],w[b]]

5

C, 390 366 363 caratteri

#define F(n)for(int i=n;i--;)
#define H(n,s,a...)F(n)printf(s);printf(a);
#define I(s)H(v,"| ",s)H(l-2,"-",s)J
#define J H(v," |","\n")
S[1<<17][26],N[1<<17],P,a;E(p){int l=strlen(gets(S[p]));if(sscanf(S[p],"%d",N+p))F(N[p])l<(a=E(++P))?l=a:l;return l+4;}R(p,v,l){if(N[p]){I(".")F(N[p])R(++P,v+1,l-4);I("'")}else{H(v,"| ","%-*s",l,S[p])J}}main(){R(P=0,0,E(0)-4);}

Compila con gcc -std=gnu99 -w file.c

Nemmeno vicino alla versione di Keith, ma ehi, è buono vecchio C


Passa solo 159 dei 160 test qui.
Joey,

Ahia. Penso che ora sia OK. Stavo dimenticando di allocare spazio per lo \ 0 nel caso estremo.
esneider,

Sembra sempre lo stesso, Test n. 142 ha esito negativo. A proposito, il caso estremo attuale non è nemmeno presente in quanto ha 10 MiB input e 78 MiB output. Non volevo che lo script di test fosse così grande ;-)
Joey,

strano, sto ottenendo 160/160 passed(intendevo una stringa di 100 caratteri, che non è presente comunque)
esneider,

Strano. FreeBSD 8.2-RELEASE #5: Sun Feb 27 10:40:25 CET 2011con gcc version 4.2.1 20070719 [FreeBSD]su x64 qui. Prenderò la tua parola per il 160, quindi :-). E in realtà dovrebbe esserci un test case con 100 caratteri (Test 143-147).
Joey,

4

pitone molto funzionale, 460 caratteri

r=range
s=lambda x:isinstance(x,str)
w=lambda x:reduce(max,[len(i)if s(i)else w(i)+4 for i in x])
z=lambda b,x:''.join(b for i in r(x))
def g(n=1):
 t=[]
 for i in r(n):
  x=raw_input('')
  try:t+=[g(int(x))]
  except:t+=[x]
 return t
o=list.append
def y(c,m):
 f='| ';h=' |';e=z('-',m+2);a='.'+e+'.';b="'"+e+"'";t=[a]
 for i in c:
  if s(i):o(t,f+i+z(' ',m-len(i))+h)
  else:[o(t,f+j+h)for j in y(i,m-4)]
 return t+[b]
x=g()[0];m=w(x);print '\n'.join(y(x,m))

Hm, questo non sembra funzionare per me i |personaggi non sono spaziati correttamente. È molto simile alla mia soluzione Python
Casey,

2
In effetti, non passa nessuno dei casi di test. eordano: li abbiamo inclusi in modo tale che nessuno potesse più inviare risposte che sono chiaramente sbagliate.
Joey,

1
Immagino di aver incollato una vecchia versione del codice. Dovrebbe funzionare ora. Mi dispiace non essere professionale.
eordano,

Per me va bene! Bella soluzione, mi piace l'approccio funzionale.
Casey,

Anzi, funziona ora.
Joey,

4

Haskell, 297 personaggi

f§(a,b)=(f a,b)
h c=(c,'-',c)
b l=h".":map(\(p,f,q)->("| "++p,f,q++" |"))l++[h"'"]
y[]s z=([(s,' ',"")],z)
y[(n,_)]_ z=b§foldr(\_(l,w)->(l++)§x w)([],z)[1..n]
x(a:z)=y(reads a)a z
m(p,_,q)=length$p++q
n®a@(p,c,q)=p++replicate(n-m a)c++q++"\n"
o(l,_)=l>>=(maximum(map m l)®)
main=interact$o.x.lines

Mentre si gioca a golf, il metodo è piuttosto semplice. Solo i limiti sono disponibili nella memoria.


4

C # - 1005 859 852 782 caratteri

using c=System.Console;using System.Linq;class N{static void Main(){new N();}N(){var i=R();c.WriteLine(i.O(0,i.G().W));}I R(){var s=c.ReadLine();int l=0,i=0;if(int.TryParse(s,out l)){var b=new I(l);for(;i<l;){b.m[i++]=R();}return b;}else{return new I(0,s);}}class P{public int W;public int H;}class I{public I[]m;bool z;string t;public I(int l,string r=""){z=l!=0;m=new I[l];t=r;}public P G(){var s=new P();if(z){var d=m.Select(i=>i.G());s.W=d.Max(y=>y.W)+4;s.H=d.Sum(y=>y.H)+2;}else{s.W=t.Length;s.H=1;}return s;}public string O(int l,int w){if(z){string s=A(l,"."+"-".PadRight(w-2,'-')+"."),e=s.Replace(".","'");foreach(var i in m){s+="\n"+i.O(l+1,w-4);}s+="\n"+e;return s;}else{return A(l,t.PadRight(w));}}}static string A(int l,string o){while(l-->0){o= "| "+o+" |";}return o;}}

Devo dare un'altra occhiata a questo dato che sono sicuro che può essere migliorato, ma questo è il mio primo passaggio iniziale .

Ungolf'd:

using c=System.Console;
using System.Linq;

class NestedBoxes
{
    static void Main()
    {
        new NestedBoxes();
    }
    NestedBoxes()
    {
        var item = ReadItem();
        c.WriteLine(item.Print(0, item.GetSize().Width));
    }
    Item ReadItem()
    {
        var line = c.ReadLine();
        int count = 0, i = 0;
        if (int.TryParse(line, out count))
        {
            var box = new Item(count);
            for (; i < count;)
            {
                box.items[i++] = ReadItem();
            }
            return box;
        }
        else
        {

            return new Item(0,line);
        }
    }
    class Size
    {
        public int Width;
        public int Height;
    }
    class Item
    {
        public Item[] items;
        bool isBox;
        string text;
        public Item(int size,string word="")
        {
            isBox = size != 0; items = new Item[size]; text = word;
        }
        public Size GetSize()
        {
            var s = new Size();
            if (isBox)
            {
                var sizes = items.Select(i => i.GetSize());
                s.Width = sizes.Max(y => y.Width) + 4; s.Height = sizes.Sum(y => y.Height) + 2;
            }
            else
            {
                s.Width = text.Length;
                s.Height = 1;
            }
            return s;
        }
        public string Print(int level, int width)
        {
            if (isBox)
            {
                string output = AddLevels(level, "." + "-".PadRight(width - 2, '-') + "."),
                        bottomLine = output.Replace(".", "'");
                foreach (var item in items)
                {
                    output += "\n" + item.Print(level + 1, width - 4);
                }
                output += "\n" + bottomLine;
                return output;
            } else {return AddLevels(level, text.PadRight(width)); }
        }
    }
    static string AddLevels(int level, string output)
    {
        while(level-->0)
        {
            output = "| " + output + " |";
        }
        return output;
    }
}

@Joey, sì, devo assolutamente ripetere tutto. È necessario giocare con la logica per provare a ridurla.
Rebecca Chernoff,

Non ho familiarità con C, ma in JS, è possibile combinare più istruzioni var a uno, in questo modo: var a = 1, b = 2, c = 3;. Non puoi fare la stessa cosa in C?
nyuszika7h

2
@ Nyuszika7H, questo è C #, non C. Non puoi combinare vardichiarazioni implicite del genere. Puoi combinare solo se hanno un tipo esplicito come Joey menzionato usando string b="",e="".
Rebecca Chernoff,

@RebeccaChernoff: ho lavorato sulla risposta degli altri ragazzi, 689 ora.
Nick Larsen,

@NickLarsen, carino - ma non sto guardando. q: Ho ancora bisogno di un po 'di tempo per esaminare il mio. Questo è stato il mio primo passo in logica, sono sicuro che ci sono posti in cui posso essere più intelligente sulla logica, ho solo bisogno di tempo per dargli attenzione.
Rebecca Chernoff,

4

PHP, 403 388 306 caratteri

<?b((int)fgets(STDIN),'');foreach($t as $r)echo$r[0].str_pad($r[2],$w-2*strlen($r[0]),$r[1]).strrev($r[0])."\n";function b($c,$p){global$t,$w;$t[]=array($p.".","-");while($c--){if(($d=trim(fgets(STDIN)))>0)b($d,"| ".$p);else$t[]=array("| ".$p," ",$d);$w=max($w,strlen($d.$p.$p)+4);}$t[]=array($p."'","-");}

Ungolfed:

box((int)fgets(STDIN), '');

foreach($table as $row) {
    $prefix = $row[0];
    $pad = $row[1];
    $data = $row[2];
    echo $prefix . str_pad($data, ($width - 2*strlen($prefix)), $pad) . strrev($prefix)."\n";
}

function box($count,$prefix) {
    global $table, $width;
    $table[] = array($prefix.".","-");
    while($count--) {
        if(($data = trim(fgets(STDIN))) > 0) {
            box($data, "| ".$prefix);
        } else {
            $table[] = array("| ".$prefix, " ", $data);
        }
        $width = max($width,strlen($data.$prefix.$prefix)+4);
    }
    $table[] = array($prefix."'","-");
}
?>

Ho preso in prestito l'idea del prefisso da Keith (è permesso a tutti?), Altrimenti è praticamente l'originale. Non riesco ancora a scendere sotto i 300. Sono bloccato con questo. In poi.


2
Bene, il codice è pubblico qui in ogni caso, quindi le idee di prestito sono consentite e forse anche incoraggiate. Penso che sia anche qualcosa che differenzia questo sito da altri simili. Come ha notato uno gnibbler , competiamo e collaboriamo allo stesso tempo .
Joey,

3

PHP, 806 769 721 653 619 caratteri

<?php function A($a,$b,$c,&$d){for($e=$b;$e>0;$e--){$f=fgets($a);if(false===$f){return;}$g=intval($f);if(0<$g){$h[]=A($a,$g,$c+1,$d);}else{$f=trim($f);$h[]=$f;$j=strlen($f)+4*$c;if($d<$j){$d=$j;}}}return $h;}$d=0;$h=A(STDIN,intval(fgets(STDIN)),1,&$d);function B($k,$c,$d){$f=str_pad('',$d-4*$c-2,'-',2);return C($k.$f.$k,$c,$d);}function C($f,$c,$d){$f=str_pad($f,$d-4*$c,' ');$f=str_pad($f,$d-2*$c,'| ',0);$f=str_pad($f,$d,' |');return $f;}function D($l,$c,$d){if(!is_array($l)){echo C($l,$c,$d)."\n";return;}echo B('.',$c,$d)."\n";foreach($l as $m){echo D($m,$c+1,$d);}echo B('\'',$c,$d)."\n";}D($h,0,$d);exit(0);?>

Versione non golfata:

<?php
function read_itemgroup($handle, $item_count, $depth, &$width) {

    //$items = array();

    for($i = $item_count; $i > 0; $i--) {
        $line = fgets( $handle );
        if(false === $line) {
            return;
        }

        $line_int = intval($line);
        if(0 < $line_int) {
            // nested group
            $items[] = read_itemgroup($handle, $line_int, $depth + 1, $width);
        }
        else {
            // standalone item
            $line = trim($line);
            $items[] = $line;

            // determine width of item at current depth
            $width_at_depth = strlen($line) + 4 * $depth;
            if($width < $width_at_depth) {
                $width = $width_at_depth;
            }
        }
    }

    return $items;
}
$width = 0;
$items = read_itemgroup(STDIN, intval(fgets( STDIN )), 1, &$width);

//var_dump($items, $width);

function render_line($corner, $depth, $width) {
    $line = str_pad('', $width - 4 * $depth - 2, '-', 2); // 2 = STR_PAD_BOTH
    return render_item($corner . $line . $corner, $depth, $width);
}

function render_item($line, $depth, $width) {
    $line = str_pad($line, $width - 4 * $depth, ' ');
    $line = str_pad($line, $width - 2 * $depth, '| ', 0); // 0 = STR_PAD_LEFT
    $line = str_pad($line, $width, ' |');
    return $line;
}

function render($item, $depth, $width) {
    if(!is_array($item)) {
        echo render_item($item, $depth, $width) . "\n";
        return;
    }
    echo render_line('.', $depth, $width) . "\n";
    foreach($item as $nested_item) {
        echo render($nested_item, $depth + 1, $width);
    }
    echo render_line('\'', $depth, $width) . "\n";
}

render($items, 0, $width);

exit(0);
?>

Perché stai usando nomi di funzioni a due lettere invece di quelli a una lettera?
Lowjacker,

@Lowkacler: buona cattura, questa è una cosa che devo ancora ottimizzare. Non avevo nessun minificatore a portata di mano, quindi l'ho fatto manualmente. Ho anche diverse idee su cosa migliorare (codewise, non minificazione), quindi posterò una versione rivista più avanti.
MicE,

1
Prima di tutto, questo manca <?a all'inizio anche a correre. Quindi apparentemente stai usando la lunghezza massima di tutti gli elementi di testo in un caso di test come larghezza per la casella più interna. Questo codice supera solo 118 dei casi di test (testati su Linux e FreeBSD). Non ho idea di cosa tu abbia fatto allo script di PowerShell che non sarebbe stato eseguito, però :-(. Invocandolo come powershell -noprofile -file test.ps1 php boxes.phpdovrebbe funzionare, in realtà. Ma non ho PHP sul mio computer Windows da testare.
Joey,

Ho provato questo sulla mia scatola usando l'ultimo script bash, ottenuto 118/156. Ho messo l'output su una sintesi
Juan

1
Bello sentire :). Questo è quello che ottengo scrivendo uno script di test inizialmente destinato all'output a riga singola ;-)
Joey,

3

Java - 681 668 caratteri

import java.util.*;public class b{static int m,h,i;public static void main(String[]a)throws Throwable{for(Object o:z("")){a=(String[])o;String s=a[0]+a[1];i=a[0].length();for(h=0;h<m-i*2-a[1].length();h++){s+=a[2];}for(h=i;h>0;h--){s+=a[0].charAt(h-1);}System.out.println(s);}}static List z(String p)throws Throwable{String b="",d="";List l=new ArrayList();while((i=System.in.read())>-1){if(10==i){if(d!=""){String[]v={p+".",b,"-"},t={p+"'",b,"-"};l.add(v);for(int u=0;u<Integer.parseInt(d);u++){l.addAll(z(p+"| "));}l.add(t);}else{h=b.length()+p.length()*2;if(m<h)m=h;String[]v={p,b," "};l.add(v);}break;}else if(i>47&&i<58){d+=(char)i;}else {b+=(char)i;}}return l;}}

essenzialmente lo stesso metodo del codice Python di Keith Randall

Versione non golfata:

import java.util.*;

public class b {
    static int m, h, i;

    public static void main(String[] a) throws Throwable {
        for (Object o : z("")) {
            a = (String[]) o;
            String s = a[0] + a[1];
            i = a[0].length();
            for (h = 0; h < m - i * 2 - a[1].length(); h++) {
                s += a[2];
            }
            for (h = i; h > 0; h--) {
                s += a[0].charAt(h - 1);
            }
            System.out.println(s);
        }
    }

    static List z(String p) throws Throwable {
        String b = "", d = "";
        List l = new ArrayList();
        while ((i = System.in.read()) > -1) {
            if (10 == i) {
                if (d != "") {
                    String[] v = { p + ".", b, "-" }, t = { p + "'", b, "-" };
                    l.add(v);
                    for (int u = 0; u < Integer.parseInt(d); u++) {
                        l.addAll(z(p + "| "));
                    }
                    l.add(t);
                } else {
                    h = b.length() + p.length() * 2;
                    if (m < h)
                        m = h;
                    String[] v = { p, b, " " };
                    l.add(v);
                }
                break;
            } else if (i > 47 && i < 58) {
                d += (char) i;
            } else {
                b += (char) i;
            }
        }
        return l;
    }
}

Penso che puoi liberarti di uno spazio ogni volta che c'è un throws.
Joey,

sì! ha anche eliminato alcuni altri caratteri. (può presumere che ogni riga sia terminata con carattere newline, ridondante break;)
Greg Schueler

probabilmente potrebbe raffinare i charconfronti guardando i codici ASCII più a lungo ... ma devo andare pronto per le vacanze
Greg Schueler,

3

Perl - 200 199 caratteri

Stesso algoritmo del Python di Keith Randall (bel design, Keith), ma un po 'più compatto in questo Perl.

sub P{$_=<>;chop;$m>($l=length"$_@_@_")or$m=$l;/^\d/?(["@_.","","-"],(map{P("| @_")}1..$_),["@_'","","-"]):["@_",$_," "]}map{($q,$t,$f)=@$_;print"$q$t",($f x($m-length"$q$t$q")).reverse($q),"\n"}(P);

1
$_@_@_sembra che qualcuno
insegua il

3

F # - 341 caratteri

let rec f(x,y)=[
 let l=stdin.ReadLine()
 let q,d=Core.int.TryParse l
 if q then
  yield x+".","",'-',"."+y
  for i=1 to d do yield!f(x+"| ",y+" |")
  yield x+"'","",'-',"'"+y
 else yield x,l,' ',y]
let l=f("","")
for w,x,y,z in l do printfn"%s"(w+x.PadRight(List.max(l|>List.map(fun(w,x,y,z)->2*w.Length+x.Length))-2*w.Length,y)+z)

Una versione F # della soluzione di Keith. Gli elenchi sono immutabili per impostazione predefinita, quindi questa versione inserisce l'intera funzione ricorsiva in un elenco, restituisce l'elenco, da cui gli elementi vengono estratti utilizzando il for..dociclo e a yield!. Non sono riuscito a trovare un modo per invertire il prefisso in modo conciso, quindi ho appena attaccato il suffisso sulle triple.

Cordiali saluti, il metodo TryParse restituisce un doppio (bool,int).


2

Clojure - 480 caratteri

(use '[clojure.contrib.string :only (repeat)])(let [r ((fn p[%](repeatedly % #(let [x (read-line)](try(doall(p(Integer/parseInt x)))(catch Exception e x))))) 1)]((fn z[m,n,o] (let[b #( let[p(dec o)](println(str(repeat p "| ")%(repeat(- m(* 4 p)2)"-")%(repeat p " |"))))](b \.)(doseq[i n](if(seq? i)(z m i(inc o))(println(str(repeat o "| ")i(repeat(- m(count i)(* o 4))" ")(repeat o " |")))))(b \')))((fn w[x](reduce max(map(fn[%](if(seq? %)(+ (w %)4)(count %)))x)))r)(first r) 1))

Questo è il mio primo programma Clojure così come il mio primo tentativo di golf Clojure, quindi, inutile dirlo, questo non dovrebbe essere considerato come rappresentativo delle soluzioni Clojure in generale. Sono sicuro che potrebbe essere abbreviato in modo significativo, soprattutto se il metodo di Keith Randall di analizzare e costruire le scatole in una volta fosse implementato.


Amico, metà di questa fonte deve essere spazio bianco. E obbligatoriamente così :-). Interessante, però, e mi chiedo se si vedrà una variante Lisp vincere un codice golf ;-)
Joey

Sono sicuro che sia possibile ... anche se come ho detto, probabilmente non sarò io a farlo.
Casey,

2

C # - 472 470 426 422 398 caratteri

using System.Linq;using y=System.Console;class W{static void Main(){var c=new int[5];var s=new string[0].ToList();int n=0,i;var l="";do{try{c[n]=int.Parse(l=y.ReadLine());l=".{1}.";n++;i=1;}catch{l+="{0}";i=0;}G:while(i++<n)l="| "+l+" |";s.Add(l);if(n>0&&--c[n-1]<0){n--;l="'{1}'";i=0;goto G;}}while(n>0);s.ForEach(z=>y.WriteLine(z,l="".PadLeft(s.Max(v=>v.Length)-z.Length),l.Replace(' ','-')));}}

Bello. A goto! A proposito, puoi omettere le parentesi attorno agli argomenti lambda ze v, portando questo al 421.
Joey

2

Scala - 475 caratteri

object N2 extends App{type S=String;def b(x:List[S],t:Int,s:S,e:S):List[S]={var l=x;o=o:+(s+".-±-."+e+"-");for(i<-1 to t)if(l.head.matches("\\d+"))l=b(l.tail,l.head.toInt,s+"| ",e+" |")else{o=o:+(s+"| "+l.head+"±"+e+" | ");l=l.drop(1)};o=o:+(s+"'-±-'"+e+"-");return l};var o:List[S]=List();val l=io.Source.stdin.getLines.toList;b(l.tail,l.head.toInt,"","");(o map(x=>x.replaceAll("±",x.last.toString*((o sortBy((_:S).length)).last.length-x.length)).dropRight(1)))map println}

1

C # 1198 1156 1142 689 671 634 caratteri

using z=System.Console;using System.Collections.Generic;using System.Linq;
class T{bool U;List<T> a=new List<T>();string m;IEnumerable<string>R(int s){if(U){yield return ".".PadRight(s-1,'-')+".";foreach(var e in a.SelectMany(b=>b.R(s-4)))yield return ("| "+e).PadRight(s-e.Length)+" |";yield return "'".PadRight(s-1,'-')+"'";}else yield return m;}int L(){return U?a.Max(x=>x.L())+4:m.Length;}
static void Main(){var p=O(int.Parse(z.ReadLine()));z.WriteLine(string.Join("\r\n",p.R(p.L())));}
static T O(int n){var k=new T(){U=true};while(n-->0){var l=z.ReadLine();int c;k.a.Add(int.TryParse(l,out c)?O(c):new T{m=l});}return k;}}

1
La versione Ungolf è disponibile su github - github.com/paulduran/CodeGolf
Fatal

Partecipare \nsembra essere sufficiente alla fine.
Joey,

Sbarazzandosi dell'interfaccia liberato molti personaggi, il resto era principalmente golf standard. C'è molto di più che si può fare qui, mi aspetto che questo possa scendere sotto i 600.
Nick Larsen,

Bel lavoro Nick. Sospettavo che l'interfaccia fosse un po 'eccessiva, a dire il vero. una semplice bandiera sarebbe bastata in questa situazione, come hai dimostrato.
Fatale

0

Pip , 89 byte (non concorrenti)

(La lingua è più recente della sfida. Inoltre, non sono riuscito a superare l'APL.)

Il codice è 87 byte, +2 per i -rnflag.

(z:{I+YPOi{Y{Vz}M,ym:MX#*Y$ALyY'|.s._.sX++m-#_.'|MyY".."J'-X++mALyAL"''"J'-Xm}yALl}i:g)

Provalo online!

La funzione zelabora il primo elemento dell'elenco di input ( g, copiato nella variabile globale in imodo da essere disponibile all'interno delle chiamate di funzione). Se questo è un numero n , si chiama ricorsivamente n volte, riempie l'elenco di linee risultante in un rettangolo completo, avvolge ciascuna linea "| " " |"e aggiunge .---.e '---'linee prima di restituire il nuovo elenco. Se è una stringa, la converte semplicemente in un elenco di un elemento e la restituisce. Il risultato finale viene stampato separato da una nuova riga ( -nflag). Maggiori dettagli disponibili su richiesta.


Di solito non ho problemi con lingue più recenti della sfida, soprattutto considerando che il problema non è così banale che una lingua appena creata avrebbe delle operazioni specifiche per risolverlo :-)
Joey,

Questo fallisce il quarto campione.
Joey,

0

Java (1369 caratteri incl. EOL)

Non potrei lasciarlo senza un'implementazione Java. Java dovrebbe essere più dettagliato delle slick di Python e Ruby, quindi ho optato per una soluzione elegante e ricorsiva.

L'idea è un albero (grafico) di oggetti (stringhe e riquadri), che contengono l'un l'altro a partire da un riquadro "head". Man mano che analizzi in modo lineare il file di input, aggiungi stringhe e riquadri alla casella "corrente" e mentre aggiungi la lunghezza massima del contenitore viene modificata. Quando un contenitore raggiunge la quantità di elementi predefiniti che può contenere il backtrack al contenitore precedente. Alla fine del file di input, hai un contenitore "head" che ha già un "maxLength" calcolato, quindi devi semplicemente chiamare il suo metodo print ().

import java.io.*;import java.util.*;
public class N{private static String rPad(String s,int l){return s+str(l-s.length(),' ');}
private static String str(int l, char c){StringBuffer sb=new StringBuffer();while(l-->0){sb.append(c);}return sb.toString();}
private static class Box {Box prnt=null;String txt=null;int items;List<Box> c=new ArrayList<Box>();int maxLength=0;
public Box(Box p,int n){prnt=p;items=n;if(p!=null){p.c.add(this);}}
public Box(Box p,String s){prnt=p;txt=s;if(p!=null){p.c.add(this);p.notify(s.length());}}
public void print(String prefix,int l,String suffix){if (txt == null){System.out.println(prefix+"."+str(l-2,'-')+"."+suffix);for(Box b:c){b.print(prefix+"| ",l-4," |"+suffix);}System.out.println(prefix+"'"+str(l-2,'-')+"'"+suffix);}else{System.out.println(prefix+rPad(txt,l)+suffix);}}
protected void notify(int l){if (l+4>this.maxLength){this.maxLength=l + 4;if (this.prnt != null){this.prnt.notify(this.maxLength);}}}}
public static void main(String[] args)throws IOException{Box head=null;Box b=null;BufferedReader in=new BufferedReader(new InputStreamReader(System.in));String s;while ((s=in.readLine()) != null){try{int n=Integer.parseInt(s);b=new Box(b, n);}catch (NumberFormatException nfe){b=new Box(b, s);}if(head == null)head=b;while ((b != null) && (b.items == b.c.size())){b=b.prnt;}}head.print("",head.maxLength,"");}}

È davvero una soluzione divertente da scrivere. Mi è piaciuta molto la domanda. Come ho detto prima, ho scelto l'eleganza della soluzione non un approccio minimalista, purtroppo Java non ha la stampa di Python "-" * 4 per produrre "----" :-)

Ecco la versione non golfata:

import java.io.*;
import java.util.*;

public class NestedBoxes
{

    private static String rPad ( String s, int l )
    {
        return s + str(l - s.length(), ' ');
    }

    private static String str ( int l, char c )
    {
        StringBuffer sb = new StringBuffer();
        while (l-- > 0)
        {
            sb.append(c);
        }
        return sb.toString();
    }

    private static class Box
    {

        Box parent = null;
        String text = null;
        int items;
        List<Box> contents = new ArrayList<Box>();

        int maxLength = 0;

        public Box ( Box p, int n )
        {
            parent = p;
            items = n;
            if (p != null)
            {
                p.contents.add(this);
            }
        }

        public Box ( Box p, String s )
        {
            parent = p;
            text = s;
            if (p != null)
            {
                p.contents.add(this);
                p.notify(s.length());
            }
        }

        public void print ( String prefix, int l, String suffix )
        {
            if (text == null)
            {
                System.out.println(prefix + "." + str(l - 2, '-') + "." + suffix);
                for (Box b : contents)
                {
                    b.print(prefix + "| ", l - 4, " |" + suffix);
                }
                System.out.println(prefix + "'" + str(l - 2, '-') + "'" + suffix);
            }
            else
            {
                System.out.println(prefix + rPad(text, l) + suffix);
            }
        }

        protected void notify ( int l )
        {
            if (l + 4 > this.maxLength)
            {
                this.maxLength = l + 4;
                if (this.parent != null)
                {
                    this.parent.notify(this.maxLength);
                }
            }
        }
    }

    public static void main ( String[] args ) throws IOException
    {
        Box head = null;
        Box b = null;
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String s;
        while ((s = in.readLine()) != null)
        {
            try
            {
                int n = Integer.parseInt(s);
                b = new Box(b, n);
            }
            catch (NumberFormatException nfe)
            {
                b = new Box(b, s);
            }

            if (head == null)
            {
                head = b;
            }

            while ((b != null) && (b.items == b.contents.size()))
            {
                b = b.parent;
            }
        }
        head.print("", head.maxLength, "");
    }
}

4
Sai, questo è un codice golf . Dovresti almeno provare a cercare una piccola soluzione. L'eleganza è tutto bello e bene, ma in realtà non è richiesto né voluto qui.
Joey,
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.