1P5: Verschachtelte Boxen

53

Diese Aufgabe ist Teil des First Periodic Premier Programming Puzzle Push .

Sie erhalten eine Hierarchie von Elementen im folgenden Format:

2
Hat
1
Gloves

die müssen in Kisten gelegt werden, wie so:

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

Im Eingabeformat beginnen die Zahlen mit einem Kästchen mit so vielen Elementen, wie die Nummer angibt. Die erste Schachtel enthält zwei Gegenstände (den Hut und die Schachtel mit den Handschuhen), die zweite enthält nur einen einzigen Gegenstand - die Handschuhe.

Wie man sieht, können Kisten auch in Kisten leben. Und sie sind immer abgerundet ... irgendwie (spitze Ecken sind eine Gefahr für Wunden und das würden wir nicht wollen).

Nachfolgend finden Sie die Details für diejenigen, die jeden noch so kleinen Spielraum nutzen möchten, den die Spezifikation bietet. Wohlgemerkt, das Nichtlesen der Spezifikation ist keine Entschuldigung für das Einreichen falscher Lösungen. Ganz am Ende stehen ein Testskript und einige Testfälle.


Spezifikation

  • Boxen bestehen aus folgenden Zeichen:

    • | (U + 007C) wird verwendet, um die vertikalen Kanten zu konstruieren.
    • - (U + 002D) wird verwendet, um die horizontalen Kanten zu konstruieren.
    • ' (U + 0027) sind die runden unteren Ecken.
    • . (U + 002E) sind die runden oberen Ecken.

    Eine Box sieht also so aus:

    .--.
    |  |
    '--'
    

    Beachten Sie, dass Unicode zwar auch runde Ecken und korrekte Box-Zeichen aufweist, diese Aufgabe jedoch nur in ASCII ausgeführt wird. So sehr ich Unicode liebe, so sehr stelle ich fest, dass es Sprachen und Umgebungen gibt, die im vorletzten Jahrzehnt noch nicht ganz angekommen sind.

  • Boxen können eine Folge von Elementen enthalten, die entweder Text oder andere Elemente sind. Einzelne Elemente in einer Box werden von oben nach unten gerendert. Die Folge A, B, C ergibt sich somit wie folgt:

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

    Dies gilt natürlich auch für verschachtelte Felder, die genau wie Text ein Element sind. Die Folge A, B, Box (C, Box (D, E)), F würde also wie folgt aussehen:

    .-----------.
    | A         |
    | B         |
    | .-------. |
    | | C     | |
    | | .---. | |
    | | | D | | |
    | | | E | | |
    | | '---' | |
    | '-------' |
    | F         |
    '-----------'
    
  • Boxen passen ihre Größe an den Inhalt an und verschachtelte Boxen erstrecken sich immer auf die Größe ihrer Eltern. Vor und nach dem Inhalt befindet sich immer ein Leerzeichen, sodass weder Text noch verschachtelte Felder zu nah am Rand des äußeren Felds sind. Kurz gesagt ist das Folgende falsch:

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

    Und das Folgende ist richtig:

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

    Sieht auch viel schöner aus :-)

  • Textelemente (siehe Eingabe unten) müssen exakt reproduziert werden.

  • Es gibt immer eine einzige Top-Level-Box (vgl. XML). Eine Box kann jedoch mehrere andere Boxen enthalten.

Eingang

  • Die Eingabe erfolgt über die Standardeingabe. zum leichteren Testen wahrscheinlich aus einer Datei umgeleitet.

  • Die Eingabe erfolgt zeilenweise, wobei jede Zeile entweder ein Textelement darstellt, das in das aktuelle Feld eingefügt werden soll, oder ein neues Feld öffnet.

  • Jede Zeile wird durch einen Zeilenumbruch abgeschlossen.

  • Textelemente werden durch eine Zeile markiert, die nicht aus einer Zahl besteht (siehe unten). Text verwendet alphabetische Zeichen, Leerzeichen und Interpunktion ( .,-'"?!()). Text beginnt oder endet nicht mit einem Leerzeichen und hat immer mindestens ein Zeichen.

  • Ein Kästchen beginnt mit einer einzelnen Zeile mit einer Zahl. Die Zahl gibt die Größe des Kartons an, dh die Anzahl der folgenden Elemente, die darin abgelegt werden:

    2
    A
    B
    

    ergibt eine Box mit zwei Textelementen:

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

    Eine Box enthält immer mindestens einen Artikel.

  • Das Ende von Feldern ist nicht explizit mit einer Linie markiert. Stattdessen werden Boxen implizit geschlossen, nachdem die angegebene Anzahl von Elementen in sie eingefügt wurde.

  • Eine Schachtel ist immer nur ein einzelnes Objekt, unabhängig davon, wie viele Objekte sich darin befinden. Z.B

    3
    A
    4
    a
    b
    c
    d
    B
    

    ergibt eine Schachtel mit drei Gegenständen, von denen der zweite eine weitere Schachtel mit vier Gegenständen ist.

    Das Verschachteln hat auch keinen Einfluss darauf, dass eine Schachtel nur ein einzelnes Objekt ist.

Grenzen

  • Die maximale Verschachtelungsstufe beträgt fünf . Dh es sind höchstens fünf Kisten ineinander. Dies schließt den äußersten ein.

  • Es gibt maximal zehn Artikel pro Karton.

  • Textelemente haben eine maximale Länge von 100 Zeichen.

Ausgabe

  • Die Ausgabe ist das gerenderte Feld, das alle enthaltenen und verschachtelten Elemente gemäß den oben angegebenen Regeln enthält.
  • Die Ausgabe sollte auf der Standardausgabe erfolgen und muss genau übereinstimmen. Es ist kein führendes oder nachfolgendes Leerzeichen zulässig.
  • Jede Zeile muss mit einem Zeilenumbruch abgeschlossen werden, einschließlich des letzten.

Gewinnbedingung

  • Kürzester Code gewinnt (dh bekommt die akzeptierte Antwort).

Probeneingabe 1

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

Beispielausgabe 1

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

Probeneingabe 2

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

Beispielausgabe 2

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

Probeneingabe 3

1
1
1
1
1
Extreme nesting Part Two

Beispielausgabe 3

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

Probeneingabe 4

3
Foo
2
Bar
Baz
2
Gak
1
Another foo?

Beispielausgabe 4

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

Skript testen

Da es manchmal schwierig sein kann, die richtigen Details zu ermitteln, haben wir ( Ventero und ich) ein Testskript erstellt, mit dem Sie Ihre Lösung ausführen können, um zu überprüfen, ob sie korrekt ist. Es ist sowohl als PowerShell-Skript als auch als Bash-Skript verfügbar . Invocation ist: <test-script> <program invocation>.

UPDATE: Die Testskripte wurden aktualisiert. Es gab eine Reihe von Testfällen, die die von mir festgelegten Grenzwerte nicht einhielten. Das PowerShell-Testskript verwendete für die Überprüfung des Ergebnisses nicht die Groß- und Kleinschreibung. Ich hoffe, jetzt ist alles in Ordnung. Die Anzahl der Testfälle wurde auf 156 reduziert, obwohl der letzte jetzt ziemlich ... groß ist.

UPDATE 2: Ich habe meinen Testfallgenerator hochgeladen . In C # geschrieben und auf die .NET 2-Laufzeit ausgerichtet. Es läuft auf Mono. Es kann Leuten helfen, ihre Implementierung zu testen. In Anbetracht der Grenzen der Aufgabe können Sie im schlimmsten Fall Folgendes versuchen:

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

Dabei werden nur Felder bis zur innersten Ebene generiert und sowohl die maximale Anzahl von Elementen pro Feld als auch die maximale Länge von Textelementen verwendet. Ich habe diesen Testfall jedoch nicht in das Testskript aufgenommen, da er ziemlich groß und die Ausgabe noch größer ist.

UPDATE 3: Ich habe das PowerShell- Testskript aktualisiert, das Fehler auslöst, je nachdem, wie die Zeilenenden im Skript sind und welche Zeilenenden die Lösung ausgibt. Jetzt sollte es für beide agnostisch sein. Entschuldigung nochmal für die Verwirrung.

Joey
quelle
Sie sagen, Boxen sollten ihre Größe an ihren Inhalt anpassen. Im letzten Beispiel passt die erste innere Box ihre Größe an die der äußeren Box an. Wie erhalten verschachtelte Boxen ihre Größe?
Juan
@ Juan: Danke, dass du das verstanden hast. Erstaunlich, dass solche Ausrutscher immer noch passieren. Bearbeitet :-)
Joey
1
@ Joey Ein oldy aber ein goody. Hoffentlich kann es einige unserer neueren Benutzer dazu inspirieren, gute, genau spezifizierte Fragen zu schreiben. :-)
Gareth
@Gareth, ich sollte auf jeden Fall versuchen, die Zeit zu finden, um wieder mehr davon zu schreiben. Aber eine genau festgelegte Frage, Testfälle, Referenzimplementierung und ähnliches (Dinge, die ich für einen Wettbewerb für wesentlich halte, aber diese Ansicht wird von vielen nicht geteilt;)) brauchen Zeit. Es war viel einfacher in Uni: D
Joey

Antworten:

2

GolfScript, 125 Zeichen

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

Verwenden Sie einen ähnlichen Ansatz wie Keith's Lösung .

Howard
quelle
26

Python, 204 Zeichen

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]

Pgibt eine Liste von Tripeln zurück, von denen jedes ein Zeilenpräfix / -suffix (das Suffix ist die Umkehrung des Präfixes), einen Zeilentext und ein Zeilenfüllzeichen enthält. Nachdem alle Tripel berechnet wurden, werden sie mit der richtigen Anzahl von Füllzeichen gedruckt, um alle Zeilen gleich lang zu machen.

Ungolfed-Version:

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]
Keith Randall
quelle
Whoa, das ging schnell. Und interessante Idee mit Pdabei.
Joey
Wow, in der Tat. Das ist interessant, kannst du die ungolfed version posten? Ich würde gerne verstehen, wie das Bewertungsbit funktioniert. Heh, meine ungolfed Python-Lösung ist 1500+ Zeichen :( Obwohl ich einen völlig anderen (und ineffizienten) Ansatz verfolge.
Casey
@Casey: eval ist nur eine Abkürzung für eine Runde, es ist nicht grundlegend. Ich werde eine ungolfed Version in einer Sekunde posten ...
Keith Randall
13

Ruby 1.9, 174 Zeichen

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}

Etwas ähnlich wie bei Keith .

Ventero
quelle
6

APL (78)

{∧/⎕D∊⍨I←⍞:{∆,('-'⍪⍵⍪'-'),∆←'.|'''/⍨1(⊃⍴⍵)1}⍕⍪/{⍵↑[2]⍨⌈/⊃∘⌽∘⍴¨∆}¨∆←∇¨⍳⍎I⋄⍉⍪I}⍬
Marinus
quelle
5
was ist das ich nicht einmal
Nowayz
Ich kann dies nicht auf tio.run ausführen, um die Lösung zu testen. Ansonsten würde ich auch die akzeptierte Antwort wechseln.
Joey
5

Python - 355 314 259 Zeichen

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
Juan
quelle
Fast 100 Zeichen weniger, gute Arbeit.
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]]
Lowjacker
quelle
5

C, 390 366 363 Zeichen

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

Kompilieren mit gcc -std=gnu99 -w file.c

Nicht einmal in der Nähe von Keiths Version, aber hey, es ist gut, alter C

esneider
quelle
Besteht hier nur 159 der 160 Tests.
Joey
Autsch. Ich denke jetzt ist es OK. Ich habe vergessen, im Extremfall Speicherplatz für \ 0 zuzuweisen.
Esneider
Sieht immer noch gleich aus, Test # 142 schlägt fehl. Übrigens ist der tatsächliche Extremfall nicht einmal vorhanden, da er einen 10-MiB-Eingang und einen 78-MiB-Ausgang hat. Ich wollte nicht, dass das Testskript so groß ist ;-)
Joey
komisch, ich bekomme 160/160 passed(ich meinte eine Zeichenfolge von 100 Zeichen, die sowieso nicht vorhanden ist)
esneider
Hm, komisch. FreeBSD 8.2-RELEASE #5: Sun Feb 27 10:40:25 CET 2011mit gcc version 4.2.1 20070719 [FreeBSD]auf x64 hier. Ich werde dann dein Wort für die 160 nehmen :-). Und es sollte tatsächlich einen Testfall mit 100 Zeichen geben (Tests 143–147).
Joey
4

sehr funktionelle Python, 460 Zeichen

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))
eordano
quelle
Hm, das scheint bei mir nicht zu funktionieren, die |Zeichen sind nicht richtig verteilt. Es ist sehr ähnlich zu meiner Python-Lösung
Casey
2
Tatsächlich besteht keiner der Testfälle. eordano: Wir haben diese mit einbezogen, damit niemand mehr falsche Antworten einreicht.
Joey
1
Ich schätze, ich habe eine alte Version des Codes eingefügt. Sollte jetzt funktionieren. Tut mir leid, dass ich unprofessionell bin.
eordano
Funktioniert bei mir! Gute Lösung, mir gefällt der funktionale Ansatz.
Casey
Funktioniert ja jetzt.
Joey
4

Haskell, 297 Zeichen

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

Während des Golfspiels ist die Methode ziemlich einfach. Nur Grenzen sind verfügbarer Speicher.

MtnViewMark
quelle
4

C # - 1005 859 852 782 Zeichen

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

Ich muss mir das noch einmal ansehen, da ich sicher bin, dass es verbessert werden kann, aber dies ist mein erster dritter Versuch.

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;
    }
}
Rebecca Chernoff
quelle
@Joey, ja, ich muss definitiv alles noch einmal durchgehen. Müssen Sie mit der Logik spielen, um zu versuchen, es auch zu verringern.
Rebecca Chernoff
Ich bin nicht vertraut mit C, aber in JS, können Sie mehr var - Anweisungen ein, wie dies kombinieren: var a = 1, b = 2, c = 3;. Kannst du nicht dasselbe in C machen?
nyuszika7h
2
@ Nyuszika7H, das ist C #, nicht C. Sie können implizite varAussagen wie diese nicht kombinieren . Sie können nur kombinieren, wenn sie einen expliziten Typ haben, wie er von Joey erwähnt wurde string b="",e="".
Rebecca Chernoff
@RebeccaChernoff: Ich habe an der Antwort der anderen Jungs gearbeitet, jetzt 689.
Nick Larsen
@NickLarsen, nett - aber ich suche nicht. F: Ich brauche noch etwas Zeit, um meine durchzuarbeiten. Dies war mein erster Versuch mit Logik. Ich bin mir sicher, dass es Orte gibt, an denen ich die Logik intelligenter angehen kann. Ich brauche nur Zeit, um ihr Aufmerksamkeit zu schenken.
Rebecca Chernoff
4

PHP, 403 388 306 Zeichen

<?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."'","-");
}
?>

Ich habe die Präfix-Idee von Keith ausgeliehen (ist das überhaupt erlaubt?), Sonst ist das ziemlich genau so wie das Original. Konnte immer noch nicht unter 300 kommen. Weiter.

Samuli K
quelle
2
Nun, Code ist hier in jedem Fall öffentlich, so dass das Ausleihen von Ideen erlaubt und vielleicht sogar gefördert wird. Ich denke, das ist auch etwas, das diese Seite von anderen, ähnlichen unterscheidet. Als Gnibbler merkte man an , dass wir gleichzeitig konkurrieren und zusammenarbeiten .
Joey
3

PHP, 806 769 721 653 619 Zeichen

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

Ungolfed-Version:

<?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);
?>
Mäuse
quelle
Warum verwenden Sie Zwei-Buchstaben-Funktionsnamen anstelle von Ein-Buchstaben-Funktionsnamen?
Lowjacker
@ Lowkacler: Guter Fang, das ist eine Sache, die ich noch optimieren muss. Ich hatte keinen Bergmann zur Hand, also habe ich das manuell gemacht. Ich habe auch einige Ideen, was zu verbessern ist (codeweise, nicht Minimierung), daher werde ich später eine überarbeitete Version veröffentlichen.
MicE
1
Zunächst fehlt dazu ein <?am Anfang noch zu laufender. Dann verwenden Sie anscheinend die maximale Länge aller Textelemente in einem Testfall als Breite für das innerste Feld. Dieser Code besteht nur 118 der Testfälle (getestet unter Linux und FreeBSD). Ich habe keine Ahnung, was Sie mit dem PowerShell-Skript gemacht haben, dass es nicht ausgeführt werden würde :-(. Es aufzurufen, wie es powershell -noprofile -file test.ps1 php boxes.phpeigentlich funktionieren sollte. Aber ich habe kein PHP auf meinem Windows-Computer zum Testen.
Joey
Getestet dies auf meiner Box mit dem neuesten Bash-Skript, bekam 118/156. Ich habe die Ausgabe auf einen Punkt gebracht
Juan
1
Schön zu hören :). Das ist, was ich zum Schreiben eines Testskripts bekomme, das ursprünglich für die Ausgabe in einer Zeile vorgesehen war ;-)
Joey,
3

Java - 681 668 Zeichen

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

Im Wesentlichen die gleiche Methode wie der Python-Code von Keith Randall

Ungolfed-Version:

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;
    }
}
Greg Schueler
quelle
Ich denke, Sie können jedes Mal, wenn es eine gibt, ein Leerzeichen loswerden throws.
Joey
Ja! beseitigte auch noch ein paar Zeichen. (Kann davon ausgehen, dass jede Zeile mit Zeilenvorschub beendet wird, redundant break;)
Greg Schueler
Wahrscheinlich könnten die charVergleiche durch längeres Betrachten der ASCII-Codes verfeinert werden ... aber ich muss mich auf den Urlaub vorbereiten
Greg Schueler
3

Perl - 200 199 Zeichen

Gleicher Algorithmus wie Keith Randalls Python (schönes Design, Keith), aber etwas kompakter in dieser Perl-Version.

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);
DCharness
quelle
1
$_@_@_sieht aus wie jemand jagt das Dollarzeichen
Ajax333221
3

F # - 341 Zeichen

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)

Eine F # -Version von Keith's Lösung. Listen sind standardmäßig unveränderlich, daher fügt diese Version die gesamte rekursive Funktion in eine Liste ein und gibt die Liste zurück, aus der die Elemente mit der for..doSchleife und a extrahiert werdenyield! . Ich konnte keinen Weg finden, das Präfix präzise umzukehren, also habe ich das Suffix einfach an die Tripel angehängt.

Zu Ihrer Information, die TryParse-Methode gibt ein double zurück (bool,int).

nharren
quelle
2

Clojure - 480 Zeichen

(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))

Dies ist mein erstes Clojure-Programm und auch mein erster Clojure-Golfversuch. Daher sollte dies nicht als repräsentativ für Clojure-Lösungen im Allgemeinen angesehen werden. Ich bin sicher, es könnte erheblich verkürzt werden, insbesondere wenn Keith Randalls Methode zum Parsen und Bauen der Boxen auf einmal implementiert würde.

Casey
quelle
Mann, die Hälfte dieser Quelle muss Leerzeichen sein. Und zwingend so :-). Interessant, und ich frage mich, ob man eine Lisp-Variante sehen wird, die einen Code-Golf gewinnt ;-)
Joey,
Ich bin mir sicher, dass es möglich ist ... obwohl ich, wie gesagt, wahrscheinlich nicht derjenige sein werde, der es tut.
Casey
2

C # - 472 470 426 422 398 Zeichen

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(' ','-')));}}
nharren
quelle
Nett. A goto! Übrigens können Sie die Klammern um die Lambda-Argumente weglassen zund vauf 421 reduzieren.
Joey
2

Scala - 475 Zeichen

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}
Gareth
quelle
1

C # 1198 1156 1142 689 671 634 Zeichen

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;}}
Tödlich
quelle
1
Ungolfed Version ist bis auf Github - github.com/paulduran/CodeGolf
Fatal
Mitmachen \nscheint am Ende zu genügen.
Joey
Das Entfernen des Interfaces hat viele Charaktere freigesetzt, der Rest war meistens Standardgolf. Es gibt viel mehr, was hier getan werden kann, ich würde erwarten, dass dies unter 600 werden könnte.
Nick Larsen
Gute Arbeit, Nick. Ich hatte den Verdacht, dass das Interface ein bisschen übertrieben war, um ehrlich zu sein. Eine einfache Flagge hätte in dieser Situation ausgereicht, wie Sie gezeigt haben.
Tödlicher
0

Pip , 89 Bytes (nicht konkurrierend)

(Die Sprache ist neuer als die Herausforderung. Außerdem konnte ich APL nicht ganz übertreffen.)

Code ist 87 Bytes, +2 für -rnFlags.

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

Probieren Sie es online!

Die Funktion zverarbeitet das erste Element der Eingabeliste ( gkopiert in eine globale Variable i, um innerhalb von Funktionsaufrufen verfügbar zu sein). Wenn dies eine Zahl n ist , ruft es sich selbst n- mal rekursiv auf, füllt die resultierende Zeilenliste zu einem vollständigen Rechteck auf "| " " |", fügt jede Zeile ein und fügt .---.und '---'Zeilen hinzu , bevor es die neue Liste zurückgibt. Wenn es sich um eine Zeichenfolge handelt, wird sie einfach in eine Liste mit einem Element konvertiert und zurückgegeben. Das Endergebnis wird durch Zeilenvorschub ( -nFlag) getrennt gedruckt . Weitere Details auf Anfrage.

DLosc
quelle
Normalerweise habe ich kein Problem mit Sprachen, die neuer sind als die Herausforderung, vor allem, wenn man bedenkt, dass das Problem nicht so trivial ist, dass eine neu erstellte Sprache Operationen speziell zum Lösen dieser Probleme hätte :-)
Joey
Das vierte Beispiel schlägt fehl.
Joey
0

Java (1369 Zeichen inkl. EOLs)

Konnte dies nicht ohne eine Java-Implementierung verlassen. Java soll ausführlicher sein als die Slicks von Python und Ruby, also habe ich mich für eine elegante, rekursive Lösung entschieden.

Die Idee ist ein Baum (Graph) von Objekten (Strings und Boxen), die sich ausgehend von einer "Kopf" Box gegenseitig enthalten. Wenn Sie die Eingabedatei linear analysieren, fügen Sie dem "aktuellen" Feld Zeichenfolgen und Felder hinzu, und während Sie hinzufügen, wird die maximale Länge des Containers angepasst. Wenn ein Container die Anzahl der vordefinierten Elemente erreicht, die Sie aufnehmen können, kehren Sie zum vorherigen Container zurück. Am Ende der Eingabedatei befindet sich ein "head" -Container, für den bereits eine "maxLength" berechnet wurde. Rufen Sie einfach die print () -Methode auf.

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

Es ist wirklich eine angenehme Lösung, um zu schreiben. Die Frage hat mir sehr gut gefallen. Wie ich bereits erwähnt habe, habe ich mich für Lösungseleganz und nicht für Minimalismus entschieden. Leider hat Java nicht Pythons Print "-" * 4 "----" :-)

Hier ist die ungolfed Version:

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, "");
    }
}
ksymeon
quelle
4
Sie wissen, das ist ein Code Golf . Sie sollten zumindest versuchen , eine kleine Lösung anzustreben. Eleganz ist alles schön und gut, aber hier nicht unbedingt erforderlich oder erwünscht.
Joey