1P5: Kotak bersarang

53

Tugas ini adalah bagian dari Push Puzzle Pemrograman Premier Periodik Pertama .

Anda mendapatkan hierarki item dalam format berikut:

2
Hat
1
Gloves

yang perlu dimasukkan ke dalam kotak, seperti:

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

Dalam format input angka mulai kotak dengan item sebanyak yang ditentukan angka. Kotak pertama memiliki dua item di dalamnya (Topi dan kotak yang berisi Sarung Tangan), yang kedua hanya berisi satu barang - sarung tangan.

Seperti yang bisa dilihat, kotak bisa hidup di dalam kotak juga. Dan mereka selalu bulat ... semacam (sudut runcing adalah bahaya luka dan kami tidak ingin itu).

Di bawah ini ada detail jahat bagi mereka yang ingin memanfaatkan setiap sedikit kelonggaran memberikan spesifikasi. Pikiran Anda, tidak membaca spesifikasi bukan alasan untuk mengirimkan solusi yang salah. Ada skrip uji dan beberapa uji kasus di bagian paling akhir.


Spesifikasi

  • Kotak dibangun dari karakter berikut:

    • | (U + 007C) digunakan untuk membangun tepi vertikal.
    • - (U + 002D) digunakan untuk membangun tepi horizontal.
    • ' (U + 0027) adalah sudut-sudut bawah bulat.
    • . (U + 002E) adalah sudut atas bulat.

    Karenanya sebuah kotak terlihat seperti ini:

    .--.
    |  |
    '--'
    

    Perhatikan bahwa sementara Unicode juga memiliki sudut bulat dan karakter menggambar kotak yang tepat, tugas ini hanya ada di ASCII. Seperti halnya saya mencintai Unicode, saya menyadari bahwa ada bahasa dan lingkungan di luar sana yang tidak tiba pada dekade kedua hingga terakhir.

  • Kotak dapat berisi urutan item yang berupa teks atau item lainnya. Masing-masing item dalam kotak dirender dari atas ke bawah. Urutan A, B, C dengan demikian menerjemahkan sebagai berikut:

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

    Ini tentu saja berlaku untuk kotak bersarang juga, yang merupakan item seperti teks. Jadi urutan A, B, Kotak (C, Kotak (D, E)), F akan merender sebagai berikut:

    .-----------.
    | A         |
    | B         |
    | .-------. |
    | | C     | |
    | | .---. | |
    | | | D | | |
    | | | E | | |
    | | '---' | |
    | '-------' |
    | F         |
    '-----------'
    
  • Kotak menyesuaikan ukurannya dengan konten dan kotak bersarang selalu melampaui ukuran induknya. Selalu ada spasi sebelum dan sesudah konten, sehingga baik teks maupun kotak bersarang tidak terlalu dekat dengan tepi kotak luar. Singkatnya, yang berikut ini salah:

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

    Dan yang berikut ini benar:

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

    Terlihat jauh lebih baik, juga :-)

  • Item teks (lihat Input di bawah) harus direproduksi dengan tepat.

  • Selalu ada satu kotak tingkat atas (lih. XML). Namun, satu kotak dapat berisi beberapa kotak lainnya.

Memasukkan

  • Input diberikan pada input standar; untuk pengujian yang lebih mudah, kemungkinan dialihkan dari file.

  • Input diberikan berdasarkan garis, dengan setiap baris mewakili item teks untuk dimasukkan ke dalam kotak saat ini atau membuka kotak baru.

  • Setiap baris diakhiri oleh satu baris.

  • Item teks ditandai oleh garis yang tidak terdiri dari angka (lihat di bawah). Teks menggunakan karakter alfabet, spasi, dan tanda baca ( .,-'"?!()). Teks tidak akan memulai atau berakhir dengan spasi dan akan selalu memiliki setidaknya satu karakter.

  • Sebuah kotak dimulai dengan satu baris dengan angka di dalamnya. Nomor tersebut memberitahu ukuran kotak, yaitu jumlah item berikut yang dimasukkan ke dalamnya:

    2
    A
    B
    

    menghasilkan kotak dengan dua item teks:

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

    Sebuah kotak akan selalu mengandung setidaknya satu item.

  • Akhir kotak tidak ditandai secara eksplisit dengan garis; sebagai gantinya kotak ditutup secara implisit setelah jumlah item yang ditentukan dimasukkan ke dalamnya.

  • Sebuah kotak selalu hanya satu item, terlepas dari berapa banyak item di dalamnya. Misalnya

    3
    A
    4
    a
    b
    c
    d
    B
    

    akan menghasilkan kotak dengan tiga item, yang kedua adalah kotak lain dengan empat item.

    Bersarang juga tidak memengaruhi fakta bahwa sebuah kotak hanyalah satu item.

Batas

  • Level bersarang maksimum adalah lima . Yaitu ada paling banyak lima kotak di dalam satu sama lain. Ini termasuk yang paling luar.

  • Maksimal sepuluh item per kotak.

  • Item teks memiliki panjang maksimal 100 karakter.

Keluaran

  • Output adalah kotak yang diberikan termasuk semua item yang mengandung dan bersarang sesuai dengan aturan yang diuraikan di atas.
  • Keluaran harus diberikan pada keluaran standar dan harus sama persis. Tidak ada spasi putih terdepan atau tambahan yang dibolehkan.
  • Setiap baris harus diakhiri dengan satu baris, termasuk yang terakhir.

Kondisi menang

  • Kode terpendek menang (yaitu mendapat jawaban yang diterima).

Masukan sampel 1

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

Output sampel 1

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

Masukan sampel 2

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

Output sampel 2

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

Masukan sampel 3

1
1
1
1
1
Extreme nesting Part Two

Keluaran sampel 3

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

Masukan sampel 4

3
Foo
2
Bar
Baz
2
Gak
1
Another foo?

Keluaran sampel 4

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

Skrip Tes

Karena mendapatkan perincian yang tepat terkadang sulit pada saat kami ( Ventero dan saya) telah menyiapkan skrip pengujian, Anda dapat menjalankan solusi dengan memeriksa apakah benar. Ini tersedia sebagai skrip PowerShell dan skrip bash . Doa adalah: <test-script> <program invocation>.

PEMBARUAN: Skrip pengujian telah diperbarui; ada sejumlah kasus uji yang tidak memenuhi batas yang saya tentukan. Skrip uji PowerShell tidak menggunakan perbandingan case-sensitive untuk memeriksa hasilnya. Saya harap semuanya baik-baik saja sekarang. Jumlah kasus uji dikurangi menjadi 156, meskipun yang terakhir sekarang cukup ... besar.

UPDATE 2: Saya mengunggah generator case-test saya . Ditulis dalam C # , menargetkan runtime .NET 2. Ini berjalan pada Mono. Ini dapat membantu orang untuk menguji implementasi mereka. Sebagai kasus terburuk yang pasti diberikan batasan dalam tugas yang dapat Anda coba:

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

yang hanya akan menghasilkan kotak hingga tingkat terdalam dan memanfaatkan jumlah item maksimum per kotak dan panjang maksimum item teks. Saya tidak memasukkan test case ini ke dalam skrip uji, karena ini cukup besar dan hasilnya lebih besar.

UPDATE 3: Saya memperbarui skrip uji PowerShell yang cenderung melempar kesalahan tergantung pada bagaimana ujung baris ada di skrip dan baris apa yang berakhir dengan solusi yang dicetak. Sekarang harus agnostik untuk keduanya. Maaf lagi atas kebingungannya.

Joey
sumber
Anda mengatakan kotak harus menyesuaikan ukurannya dengan konten mereka. Namun dalam contoh terakhir, kotak dalam pertama menyesuaikan ukurannya dengan kotak luar. Jadi, bagaimana kotak bersarang mendapatkan ukurannya?
Juan
@Juan: Terima kasih sudah menangkapnya. Luar biasa yang tergelincir seperti itu masih terjadi. Diedit :-)
Joey
1
@ Joey An oldy but a goody. Semoga ini dapat menginspirasi beberapa pengguna baru kami untuk menulis pertanyaan yang baik dan spesifik. :-)
Gareth
@ Gareth, saya pasti harus mencoba menemukan waktu untuk menulis lebih banyak lagi. Tetapi pertanyaan yang ditentukan dengan baik, kasus uji, implementasi referensi dan hal-hal (hal-hal yang saya anggap penting untuk sebuah kompetisi, tetapi pandangan itu tidak dimiliki oleh banyak orang;)) membutuhkan waktu. Itu jauh lebih mudah saat di universitas: D
Joey

Jawaban:

2

GolfScript, 125 karakter

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

Menggunakan pendekatan serupa sebagai solusi Keith .

Howard
sumber
26

Python, 204 karakter

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]

Pmengembalikan daftar tiga kali lipat, masing-masing merupakan awalan baris / akhiran (akhiran kebalikan dari awalan), beberapa teks baris, dan karakter baris mengisi. Setelah menghitung semua tiga kali lipat, mereka dicetak menggunakan jumlah karakter isi yang tepat untuk membuat semua garis sama panjang.

Versi tidak disatukan:

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
sumber
Wah, itu cepat. Dan ide yang menarik dengan Pitu.
Joey
Wow, tentu saja. Ini menarik, bisakah Anda memposting versi yang tidak di-serigala? Saya ingin memahami bagaimana bit eval bekerja. Heh, solusi python saya yang tidak diserang adalah 1500+ karakter :( Meskipun saya mengambil pendekatan yang sama sekali berbeda (dan tidak efisien).
Casey
@Casey: eval hanyalah jalan pintas golf untuk loop, itu tidak mendasar. Saya akan memposting versi yang tidak diklik dalam beberapa detik ...
Keith Randall
13

Ruby 1.9, 174 karakter

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}

Agak mirip dengan solusi Keith .

Ventero
sumber
6

APL (78)

{∧/⎕D∊⍨I←⍞:{∆,('-'⍪⍵⍪'-'),∆←'.|'''/⍨1(⊃⍴⍵)1}⍕⍪/{⍵↑[2]⍨⌈/⊃∘⌽∘⍴¨∆}¨∆←∇¨⍳⍎I⋄⍉⍪I}⍬
marinus
sumber
5
apa ini saya bahkan tidak
Nowayz
Saya tidak bisa menjalankan ini pada tio.run untuk menguji solusinya. Kalau tidak, saya akan mengganti jawaban yang diterima juga.
Joey
5

Python - 355 314 259 karakter

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
sumber
pengurangan hampir 100 char, kerja bagus.
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
sumber
5

C, 390 366 363 karakter

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

Kompilasi dengan gcc -std=gnu99 -w file.c

Bahkan tidak dekat dengan versi Keith, tapi hei, itu bagus ol 'C

esneider
sumber
Lulus hanya 159 dari 160 tes di sini.
Joey
Aduh. Saya pikir sekarang tidak apa-apa. Saya lupa mengalokasikan ruang untuk \ 0 dalam kasus ekstrim.
esneider
Terlihat masih sama, Tes # 142 gagal. Omong-omong, kasus ekstrem yang sebenarnya bahkan tidak ada karena memiliki 10 input MiB dan 78 output MiB. Saya tidak ingin skrip tes menjadi sebesar itu ;-)
Joey
aneh, saya mengerti 160/160 passed(maksud saya serangkaian 100 karakter, yang toh tidak ada)
esneider
Hm, aneh. FreeBSD 8.2-RELEASE #5: Sun Feb 27 10:40:25 CET 2011dengan gcc version 4.2.1 20070719 [FreeBSD]pada x64 di sini. Saya akan mengambil kata-kata Anda untuk 160, lalu :-). Dan seharusnya ada test case dengan 100 karakter, sebenarnya (Tes 143-147).
Joey
4

python sangat fungsional, 460 karakter

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
sumber
Hm, ini sepertinya tidak berfungsi untuk saya karena |karakter tidak diberi spasi dengan benar. Ini sangat mirip dengan solusi python saya
Casey
2
Memang, tidak lulus uji kasus. eordano: Kami memasukkan itu sehingga tidak ada yang akan mengirimkan jawaban yang jelas salah lagi.
Joey
1
Saya kira saya menempelkan kode versi lama. Harusnya bekerja sekarang. Maaf karena tidak profesional.
eordano
Bekerja untukku! Solusi yang bagus, saya suka pendekatan fungsional.
Casey
Memang, berhasil sekarang.
Joey
4

Haskell, 297 karakter

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

Saat bermain golf, metodenya cukup lurus ke depan. Hanya batas memori yang tersedia.

MtnViewMark
sumber
4

C # - 1005 859 852 782 karakter

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

Saya perlu melihat ini lagi karena saya yakin ini bisa diperbaiki, tapi ini adalah langkah ketiga saya yang pertama .

Tidak Digolkan:

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
sumber
@ Joey, ya, saya pasti harus melewati semua itu lagi. Perlu bermain dengan logika untuk mencoba dan memotongnya juga.
Rebecca Chernoff
Aku tidak akrab dengan C, tetapi dalam JS, Anda dapat menggabungkan beberapa pernyataan var satu, seperti ini: var a = 1, b = 2, c = 3;. Tidak bisakah kamu melakukan hal yang sama dalam C?
nyuszika7h
2
@ Nyuszika7H, ini C #, bukan C. Anda tidak bisa menggabungkan varpernyataan implisit seperti itu. Anda hanya dapat menggabungkan jika mereka memiliki tipe eksplisit seperti Joey disebutkan menggunakan string b="",e="".
Rebecca Chernoff
@RebeccaChernoff: Saya mengerjakan jawaban orang lain, 689 sekarang.
Nick Larsen
@NickLarsen, bagus - tapi saya tidak melihat. T: Saya masih perlu waktu untuk menjalani tambang. Ini adalah langkah awal saya pada logika, saya yakin ada tempat saya bisa lebih pintar tentang logika, hanya perlu waktu untuk memberikan perhatian.
Rebecca Chernoff
4

PHP, 403 388 306 karakter

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

Tidak Disatukan:

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

Saya meminjam ide awalan dari Keith (apakah itu diizinkan sama sekali?), Kalau tidak, ini hampir sama dengan aslinya. Masih belum bisa di bawah 300. Terjebak dengan ini. Dan seterusnya.

Samuli K
sumber
2
Nah, kode bersifat publik di sini dalam setiap kasus, jadi ide-ide pinjaman diperbolehkan dan mungkin bahkan dianjurkan. Saya pikir itu juga sesuatu yang membedakan situs ini dari yang lain, yang serupa. Seperti yang dicatat oleh gnibbler, kami bersaing dan berkolaborasi pada saat yang sama .
Joey
3

PHP, 806 769 721 653 619 karakter

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

Versi tidak disatukan:

<?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);
?>
MicE
sumber
Mengapa Anda menggunakan nama fungsi dua huruf, bukan yang satu huruf?
Lowjacker
@ Lowkacler: tangkapan bagus, itu satu hal yang masih perlu saya optimalkan. Saya tidak memiliki alat penggosok, jadi saya melakukannya secara manual. Saya juga punya beberapa ide tentang apa yang harus ditingkatkan (codewise, bukan minification), jadi saya akan memposting versi revisi nanti.
MicE
1
Pertama-tama, ini hilang <?pada awalnya untuk menjalankan. Maka Anda tampaknya menggunakan panjang maksimum semua item teks dalam kotak uji sebagai lebar untuk kotak paling dalam. Kode ini hanya melewati 118 kasus uji (diuji di Linux dan FreeBSD). Saya tidak tahu apa yang Anda lakukan pada skrip PowerShell yang tidak akan berjalan, meskipun :-(. Memanggilnya seperti powershell -noprofile -file test.ps1 php boxes.phpseharusnya bekerja, sebenarnya. Tapi saya tidak punya PHP untuk diuji pada mesin Windows saya.
Joey
Menguji ini di kotak saya menggunakan skrip bash terbaru, mendapat 118/156. Saya menempatkan output pada intisari
Juan
1
Senang mendengarnya :). Itulah yang saya dapatkan untuk menulis skrip uji yang awalnya dimaksudkan untuk output satu baris ;-)
Joey
3

Java - 681 668 karakter

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

dasarnya metode yang sama dengan kode Python Keith Randall

Versi tidak disatukan:

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
sumber
Saya pikir Anda dapat menyingkirkan satu ruang setiap kali ada throws.
Joey
Iya! juga memperpanjang beberapa karakter lagi. (dapat mengasumsikan setiap baris diakhiri dengan baris baru, berlebihan break;)
Greg Schueler
mungkin bisa menyempurnakan charperbandingan dengan melihat kode ascii lebih lama ... tetapi saya harus bersiap-siap untuk liburan
Greg Schueler
3

Perl - 200 199 karakter

Algoritma yang sama dengan Python Keith Randall (desain yang bagus, Keith), tetapi sedikit lebih ringkas dalam Perl ini.

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
sumber
1
$_@_@_Sepertinya seseorang mengejar tanda dolar
ajax333221
3

F # - 341 karakter

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)

Versi F # dari solusi Keith. Daftar tidak dapat diubah secara default, jadi versi ini memasukkan seluruh fungsi rekursif ke dalam daftar, mengembalikan daftar, dari mana item diekstraksi menggunakan for..doloop dan a yield!. Saya tidak bisa menemukan cara untuk membalikkan awalan secara ringkas, jadi saya hanya menempelkan suffix ke triples.

FYI, metode TryParse mengembalikan ganda (bool,int).

nharren
sumber
2

Clojure - 480 karakter

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

Ini adalah program Clojure pertama saya serta upaya golf Clojure pertama saya, jadi, tak perlu dikatakan, ini tidak boleh dianggap sebagai perwakilan dari solusi Clojure secara umum. Saya yakin itu bisa diperpendek secara signifikan, terutama jika metode parsing dan membangun kotak Keith Randall diimplementasikan sekaligus.

Casey
sumber
Man, setengah dari sumber ini harus spasi putih. Dan wajib jadi :-). Menarik, dan saya ingin tahu apakah orang akan melihat varian Lisp memenangkan kode golf ;-)
Joey
Saya yakin itu mungkin ... meskipun seperti saya katakan, saya mungkin tidak akan menjadi orang yang melakukannya.
Casey
2

C # - 472 470 426 422 398 karakter

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
sumber
Bagus. A goto! Ngomong-ngomong, Anda bisa menghilangkan tanda kurung di sekitar argumen lambda zdan v, membawanya ke 421.
Joey
2

Scala - 475 karakter

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
sumber
1

C # 1198 1156 1142 689 671 634 Karakter

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;}}
Fatal
sumber
1
Versi tidak berkerangka ada di github - github.com/paulduran/CodeGolf
Fatal
Bergabung dengan \ntampaknya cukup pada akhirnya.
Joey
Menyingkirkan antarmuka membebaskan banyak karakter, sisanya sebagian besar golf standar. Ada banyak lagi yang bisa dilakukan di sini, saya berharap ini bisa di bawah 600.
Nick Larsen
Kerja bagus, Nick. Saya curiga antarmuka sedikit berlebihan, jujur. bendera sederhana sudah mencukupi dalam situasi ini seperti yang telah Anda tunjukkan.
Fatal
0

Pip , 89 byte (tidak bersaing)

(Bahasa lebih baru daripada tantangan. Juga, saya tidak bisa cukup mengungguli APL.)

Kode adalah 87 byte, +2 untuk -rnbendera.

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

Cobalah online!

Fungsi zmemproses item pertama dari daftar input ( g, disalin ke variabel global iagar tersedia di dalam panggilan fungsi). Jika ini adalah angka n , ia menyebut dirinya secara berulang n kali, menyambungkan daftar garis yang dihasilkan ke sebuah persegi panjang penuh, membungkus setiap baris "| " " |", dan menambahkan .---.dan '---'baris sebelum mengembalikan daftar baru. Jika ini adalah string, itu hanya mengubahnya menjadi daftar satu item dan mengembalikannya. Hasil akhir dicetak dipisahkan baris-baru ( -nbendera). Detail lebih lanjut tersedia berdasarkan permintaan.

DLosc
sumber
Saya biasanya tidak memiliki masalah dengan bahasa yang lebih baru daripada tantangan, terutama mengingat bahwa masalahnya tidak sepele sehingga bahasa yang baru dibuat akan memiliki operasi khusus untuk menyelesaikannya :-)
Joey
Ini gagal sampel keempat.
Joey
0

Java (1369 karakter termasuk EOL)

Tidak dapat meninggalkan ini tanpa implementasi Java. Java seharusnya lebih bertele-tele daripada slice Python dan Ruby, jadi saya mencari solusi rekursif yang elegan.

Idenya adalah Pohon (Grafik) objek (string dan kotak), berisi satu sama lain mulai dari kotak "kepala". Saat Anda mem-parsing file input secara linear, Anda menambahkan string dan kotak ke kotak "saat ini" dan saat Anda menambahkan panjang maksimum wadah disesuaikan. Ketika sebuah kontainer mencapai jumlah item yang telah ditentukan yang dapat menahan Anda mundur ke kontainer sebelumnya. Di akhir file input, Anda memiliki wadah "head" yang sudah memiliki "maxLength" yang dihitung, jadi Anda cukup memanggil metode 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,"");}}

Benar-benar solusi yang menyenangkan untuk menulis. Saya sangat menyukai pertanyaan itu. Seperti yang saya sebutkan sebelumnya, saya mencari solusi keanggunan bukan pendekatan minimalis, sayangnya Java tidak memiliki cetakan Python "-" * 4 untuk menghasilkan "----" :-)

Ini versi yang tidak dikoleksi:

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
sumber
4
Anda tahu, ini adalah kode golf . Anda setidaknya harus mencoba membidik solusi kecil . Keanggunan semuanya bagus dan baik, tetapi tidak benar-benar diperlukan atau diinginkan di sini.
Joey