1P5: Hộp lồng nhau


53

Nhiệm vụ này là một phần của Câu đố đẩy lập trình Premier định kỳ đầu tiên .

Bạn nhận được một hệ thống phân cấp của các mục theo định dạng sau:

2
Hat
1
Gloves

cần phải được đặt trong hộp, như vậy:

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

Trong định dạng đầu vào, các số bắt đầu một hộp có nhiều mục như số chỉ định. Hộp thứ nhất có hai vật phẩm trong đó (Mũ và hộp chứa Găng tay), hộp thứ hai chỉ chứa một vật phẩm duy nhất - găng tay.

Có thể thấy, hộp cũng có thể sống trong hộp. Và chúng luôn được làm tròn ... loại (góc nhọn là mối nguy hiểm và chúng tôi không muốn điều đó).

Dưới đây là các chi tiết khó chịu cho những người muốn sử dụng từng chút thời gian mà thông số kỹ thuật đưa ra. Tâm trí bạn, không đọc thông số kỹ thuật là không có lý do để gửi giải pháp sai. Có một kịch bản thử nghiệm và một vài trường hợp thử nghiệm ở cuối.


Đặc điểm kỹ thuật

  • Hộp được xây dựng từ các nhân vật sau:

    • | (U + 007C) được sử dụng để xây dựng các cạnh dọc.
    • - (U + 002D) được sử dụng để xây dựng các cạnh ngang.
    • ' (U + 0027) là các góc dưới tròn.
    • . (U + 002E) là các góc trên tròn.

    Do đó, một hộp trông như thế này:

    .--.
    |  |
    '--'
    

    Lưu ý rằng mặc dù Unicode cũng có các góc tròn và các ký tự vẽ hộp thích hợp, nhưng tác vụ này chỉ ở dạng ASCII. Nhiều như tôi yêu thích Unicode Tôi nhận ra rằng có những ngôn ngữ và môi trường ngoài kia không hoàn toàn xuất hiện trong thập kỷ thứ hai đến thập kỷ trước.

  • Các hộp có thể chứa một chuỗi các mục là văn bản hoặc các mục khác. Các mục riêng lẻ trong một hộp được hiển thị từ trên xuống dưới. Trình tự A, B, C do đó biểu hiện như sau:

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

    Điều này tất nhiên áp dụng cho các hộp lồng nhau, đó là một mục giống như văn bản. Vì vậy, chuỗi A, B, Box (C, Box (D, E)), F sẽ hiển thị như sau:

    .-----------.
    | A         |
    | B         |
    | .-------. |
    | | C     | |
    | | .---. | |
    | | | D | | |
    | | | E | | |
    | | '---' | |
    | '-------' |
    | F         |
    '-----------'
    
  • Các hộp điều chỉnh kích thước của chúng theo nội dung và các hộp lồng nhau luôn mở rộng theo kích thước của bố mẹ chúng. Luôn có một khoảng trắng trước và sau nội dung, sao cho cả hộp văn bản và hộp lồng nhau quá gần với cạnh của hộp bên ngoài. Nói tóm lại, những điều sau là sai:

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

    Và sau đây là chính xác:

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

    Trông cũng đẹp hơn nhiều :-)

  • Các mục văn bản (xem Đầu vào bên dưới) phải được sao chép chính xác.

  • Luôn có một hộp cấp cao nhất (xem XML). Tuy nhiên, một hộp có thể chứa một số hộp khác.

Đầu vào

  • Đầu vào được đưa ra trên đầu vào tiêu chuẩn; để kiểm tra dễ dàng hơn có khả năng chuyển hướng từ một tập tin.

  • Đầu vào được đưa ra theo dòng, với mỗi dòng đại diện cho một mục văn bản để đặt vào hộp hiện tại hoặc mở một hộp mới.

  • Mỗi dòng được kết thúc bởi một ngắt dòng.

  • Các mục văn bản được đánh dấu bằng một dòng không bao gồm một số (xem bên dưới). Văn bản sử dụng các ký tự chữ cái, dấu cách và dấu chấm câu ( .,-'"?!()). Văn bản sẽ không bắt đầu hoặc kết thúc bằng một khoảng trắng và nó sẽ luôn có ít nhất một ký tự.

  • Một hộp bắt đầu với một dòng duy nhất có một số trong đó. Con số cho biết kích thước của hộp, tức là số lượng vật phẩm sau đây được đặt vào nó:

    2
    A
    B
    

    mang lại một hộp có hai mục văn bản:

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

    Một hộp sẽ luôn chứa ít nhất một mục.

  • Phần cuối của hộp không được đánh dấu rõ ràng bằng một dòng; thay vào đó các hộp được đóng hoàn toàn sau khi số lượng vật phẩm quy định được đưa vào chúng.

  • Một hộp luôn chỉ là một vật phẩm duy nhất, bất kể có bao nhiêu vật phẩm trong đó. Ví dụ

    3
    A
    4
    a
    b
    c
    d
    B
    

    sẽ mang lại một hộp có ba vật phẩm, thứ hai là một hộp khác có bốn vật phẩm.

    Nesting cũng không ảnh hưởng đến thực tế là một hộp chỉ là một mục duy nhất.

Hạn mức

  • Mức lồng tối đa là năm . Tức là có nhiều nhất năm hộp bên trong nhau. Điều này bao gồm một ngoài cùng.

  • Có tối đa mười mặt hàng mỗi hộp.

  • Các mục văn bản có độ dài tối đa 100 ký tự.

Đầu ra

  • Đầu ra là hộp kết xuất bao gồm tất cả các mục chứa và lồng nhau theo các quy tắc được nêu ở trên.
  • Đầu ra phải được đưa ra trên đầu ra tiêu chuẩn và nó phải khớp chính xác. Không có khoảng trắng hàng đầu hoặc dấu được cho phép.
  • Mỗi dòng phải được kết thúc bằng một ngắt dòng, bao gồm cả dòng cuối cùng.

Điều kiện chiến thắng

  • Mã ngắn nhất sẽ thắng (tức là nhận được câu trả lời được chấp nhận).

Mẫu đầu vào 1

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

Sản lượng mẫu 1

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

Mẫu đầu vào 2

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

Sản lượng mẫu 2

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

Mẫu đầu vào 3

1
1
1
1
1
Extreme nesting Part Two

Sản lượng mẫu 3

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

Mẫu đầu vào 4

3
Foo
2
Bar
Baz
2
Gak
1
Another foo?

Sản lượng mẫu 4

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

Kiểm tra tập lệnh

Vì việc cung cấp thông tin chi tiết có thể rất khó khăn, đôi khi chúng tôi ( Ventero và tôi) đã chuẩn bị một kịch bản thử nghiệm, bạn có thể chạy giải pháp của mình để kiểm tra xem nó có đúng không. Nó có sẵn ở cả tập lệnh PowerShelltập lệnh bash . Cầu nguyện là : <test-script> <program invocation>.

CẬP NHẬT: Các kịch bản thử nghiệm đã được cập nhật; có một số trường hợp thử nghiệm không tôn trọng các giới hạn tôi đã xác định. Tập lệnh kiểm tra PowerShell không sử dụng so sánh phân biệt chữ hoa chữ thường để kiểm tra kết quả. Tôi hy vọng mọi thứ đều ổn bây giờ. Số lượng các trường hợp thử nghiệm đã giảm xuống còn 156, mặc dù trường hợp cuối cùng bây giờ khá ... lớn.

CẬP NHẬT 2: Tôi đã tải lên trình tạo trường hợp thử nghiệm của mình . Được viết bằng C # , nhắm mục tiêu thời gian chạy .NET 2. Nó chạy trên Mono. Nó có thể giúp mọi người kiểm tra việc thực hiện của họ. Như một trường hợp xấu nhất chắc chắn đưa ra các giới hạn trong nhiệm vụ bạn có thể thử:

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

sẽ chỉ tạo các hộp cho đến mức trong cùng và sử dụng cả số lượng mục tối đa trên mỗi hộp và độ dài tối đa của các mục văn bản. Mặc dù vậy, tôi đã không đưa trường hợp thử nghiệm này vào tập lệnh thử nghiệm, vì nó khá lớn và sản lượng thậm chí còn lớn hơn.

CẬP NHẬT 3: Tôi đã cập nhật tập lệnh kiểm tra PowerShell có xu hướng bị lỗi tùy thuộc vào cách kết thúc dòng trong tập lệnh và dòng kết thúc giải pháp được in. Bây giờ nó nên là bất khả tri cho cả hai. Xin lỗi lần nữa vì sự nhầm lẫn.


Bạn nói hộp nên điều chỉnh kích thước của chúng theo nội dung của chúng. Tuy nhiên, trong ví dụ cuối cùng, hộp bên trong đầu tiên điều chỉnh kích thước của nó với hộp bên ngoài. Vì vậy, làm thế nào để lồng hộp có được kích thước của họ?
Juan

@Juan: Cảm ơn vì đã nắm bắt điều đó. Thật ngạc nhiên khi trượt như những điều vẫn còn xảy ra. Đã chỉnh sửa :-)
Joey

1
@Joey Một người già nhưng tốt bụng. Hy vọng rằng nó có thể truyền cảm hứng cho một số người dùng mới hơn của chúng tôi để viết các câu hỏi hay, được chỉ định tốt. :-)
Gareth

@Gareth, tôi chắc chắn nên cố gắng tìm thời gian để viết thêm những thứ đó một lần nữa. Nhưng một câu hỏi được chỉ định rõ, các trường hợp thử nghiệm, triển khai tham chiếu và nội dung (những điều tôi cho là cần thiết cho một cuộc thi, nhưng quan điểm đó không được nhiều người chia sẻ;)) cần có thời gian. Nó dễ dàng hơn nhiều khi ở uni: D
Joey

Câu trả lời:


2

GolfScript, 125 ký tự

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

Sử dụng một cách tiếp cận tương tự như giải pháp của Keith .


26

Python, 204 ký tự

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]

Ptrả về một danh sách các bộ ba, mỗi bộ là một tiền tố / hậu tố dòng (hậu tố là đảo ngược của tiền tố), một số văn bản dòng và ký tự điền dòng. Sau khi tính toán tất cả các bộ ba, chúng được in bằng cách sử dụng đúng số ký tự điền để làm cho tất cả các dòng có cùng độ dài.

Phiên bản bị đánh cắp:

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, thật nhanh chóng. Và ý tưởng thú vị với Pđó.
Joey

Wow, thực sự. Điều này thật thú vị, bạn có thể đăng phiên bản vô văn hóa không? Tôi muốn hiểu làm thế nào bit eval hoạt động. Heh, giải pháp trăn không có kiến ​​thức của tôi là hơn 1500 ký tự :( Mặc dù tôi có một cách tiếp cận hoàn toàn khác (và không hiệu quả).
Casey

@Casey: eval chỉ là một lối tắt chơi gôn cho một vòng lặp, nó không phải là cơ bản. Tôi sẽ đăng một phiên bản không có bản quyền trong một giây ...
Keith Randall

13

Ruby 1.9, 174 ký tự

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}

Khá giống với giải pháp của Keith .


6

APL (78)

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

5
những gì tôi thậm chí không
Nowayz

Tôi không thể có được điều này để chạy trên tio.run để kiểm tra giải pháp. Nếu không, tôi cũng sẽ chuyển câu trả lời được chấp nhận.
Joey

5

Python - 355 314 259 ký tự

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

giảm gần 100 char, công việc tốt.
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 ký tự

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

Biên dịch với gcc -std=gnu99 -w file.c

Thậm chí không gần với phiên bản của Keith, nhưng này, nó rất tốt


Chỉ vượt qua 159 trong số 160 bài kiểm tra ở đây.
Joey

Ôi. Tôi nghĩ bây giờ nó ổn. Tôi đã quên phân bổ không gian cho \ 0 trong trường hợp cực đoan.
esneider

Trông vẫn như cũ, Bài kiểm tra # 142 thất bại. Nhân tiện, trường hợp cực đoan thực tế thậm chí không xuất hiện vì nó có 10 đầu vào MiB và đầu ra 78 MiB. Tôi không muốn kịch bản thử nghiệm lớn đến thế ;-)
Joey

160/160 passedThật kỳ lạ, tôi đang nhận được (ý tôi là một chuỗi gồm 100 ký tự, dù sao nó cũng không có)
esneider

Hừm, lạ quá. FreeBSD 8.2-RELEASE #5: Sun Feb 27 10:40:25 CET 2011với gcc version 4.2.1 20070719 [FreeBSD]x64 ở đây. Tôi sẽ nhận lời của bạn cho 160, sau đó :-). Và thực sự nên có một trường hợp thử nghiệm với 100 ký tự (Thử nghiệm 143 Hàng147).
Joey

4

trăn rất chức năng, 460 ký tự

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

Hừm, điều này dường như không hoạt động đối với tôi, các |ký tự không được đặt đúng cách. Nó rất giống với giải pháp python của tôi
Casey

2
Thật vậy, không vượt qua bất kỳ trường hợp thử nghiệm. eordano: Chúng tôi bao gồm những câu hỏi đó để không ai gửi câu trả lời sai nữa.
Joey

1
Tôi đoán tôi đã dán một phiên bản cũ của mã. Nên làm việc bây giờ. Xin lỗi về việc không chuyên nghiệp.
eordano

Làm việc cho tôi! Giải pháp tốt đẹp, tôi thích cách tiếp cận chức năng.
Casey

Thật vậy, làm việc bây giờ.
Joey

4

Haskell, 297 ký tự

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

Trong khi chơi gôn, phương pháp này khá đơn giản. Chỉ giới hạn là bộ nhớ có sẵn.


4

C # - 1005 859 852 782 ký tự

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

Tôi cần phải có cái nhìn khác về điều này vì tôi chắc chắn rằng nó có thể được cải thiện, nhưng đây là lần thứ ba tôi vượt qua nó.

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, yeah, tôi chắc chắn cần phải trải qua tất cả một lần nữa. Cần phải chơi với logic để thử và cắt nó xuống.
Rebecca Chernoff

Tôi không quen thuộc với C, nhưng trong JS, bạn có thể kết hợp nhiều câu lệnh var thành một, như thế này : var a = 1, b = 2, c = 3;. Bạn không thể làm điều tương tự trong C?
nyuszika7h

2
@ Nyuszika7H, đây là C #, không phải C. Bạn không thể kết hợp các vartuyên bố ngầm như thế. Bạn chỉ có thể kết hợp nếu họ có một loại rõ ràng như Joey đã đề cập bằng cách sử dụng string b="",e="".
Rebecca Chernoff

@RebeccaCécoff: Tôi đã làm việc với những người khác trả lời, 689 bây giờ.
Nick Larsen

@NickLarsen, tốt - nhưng tôi không tìm kiếm. q: Tôi vẫn cần một chút thời gian để đi qua của tôi. Đây là bước đi đầu tiên của tôi về logic, tôi chắc chắn có những nơi tôi có thể thông minh hơn về logic, chỉ cần thời gian để khiến nó chú ý.
Rebecca Chernoff

4

PHP, 403 388 306 ký tự

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

Ung dung:

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

Tôi đã mượn ý tưởng tiền tố từ Keith (điều đó có được phép không?), Nếu không thì điều này khá giống với bản gốc. Vẫn không thể có được dưới 300. Bị mắc kẹt với điều này. Trở đi


2
Vâng, mã được công khai ở đây trong mọi trường hợp, vì vậy việc mượn ý tưởng được cho phép và thậm chí có thể được khuyến khích. Tôi nghĩ đó cũng là một cái gì đó khác biệt trang web này với trang web khác, tương tự. Như gnibbler, một người lưu ý rằng chúng tôi cạnh tranh và hợp tác cùng một lúc .
Joey

3

PHP, 806 769 721 653 619 ký tự

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

Phiên bản bị đánh cắp:

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

Tại sao bạn sử dụng tên hàm hai chữ cái thay vì tên một chữ cái?
Lowjacker

@Lowkacler: nắm bắt tốt, đó là một điều mà tôi vẫn cần tối ưu hóa. Tôi không có bất kỳ công cụ khai thác nào trong tay, vì vậy tôi đã làm điều đó bằng tay. Tôi cũng có một vài ý tưởng về những gì cần cải thiện (mã hóa, không phải giảm thiểu), vì vậy tôi sẽ đăng một phiên bản sửa đổi sau này.
MicE

1
Trước hết, điều này là thiếu một <?trong đầu để thậm chí chạy. Sau đó, rõ ràng bạn đang sử dụng độ dài tối đa của tất cả các mục văn bản trong trường hợp thử nghiệm làm chiều rộng cho hộp trong cùng. Mã này chỉ vượt qua 118 trường hợp thử nghiệm (được thử nghiệm trên Linux và FreeBSD). Tôi không có ý tưởng những gì bạn đã làm cho kịch bản PowerShell rằng nó sẽ không chạy, mặc dù :-( Gọi nó như là. powershell -noprofile -file test.ps1 php boxes.phpNên làm việc, thực sự Nhưng tôi không có PHP trên máy tính Windows của tôi để kiểm tra..
Joey

Đã thử nghiệm điều này trên hộp của tôi bằng cách sử dụng tập lệnh bash mới nhất, nhận được 118/156. Tôi đặt đầu ra trên một ý chính
Juan

1
Rất vui được nghe :). Đó là những gì tôi nhận được khi viết một kịch bản thử nghiệm ban đầu được dự định cho đầu ra một dòng ;-)
Joey

3

Java - 681 668 ký tự

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

về cơ bản là cùng một phương thức với mã Python của Keith Randall

Phiên bản bị đánh cắp:

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

Tôi nghĩ rằng bạn có thể thoát khỏi một không gian mỗi lần có một throws.
Joey

Đúng! cũng kéo dài thêm một vài ký tự. (có thể giả sử mỗi dòng được kết thúc bằng char dòng mới, dự phòng break;)
Greg Schueler

có lẽ có thể làm sáng tỏ sự charso sánh bằng cách xem mã ascii lâu hơn ... nhưng tôi phải chuẩn bị đi nghỉ
Greg Schueler

3

Perl - 200 199 ký tự

Thuật toán tương tự như Python của Keith Randall (thiết kế đẹp, Keith), nhưng nhỏ gọn hơn một chút trong Perl này đảm nhận nó.

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
$_@_@_trông giống như ai đó đang theo đuổi ký hiệu đô la
ajax333221

3

F # - 341 ký tự

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)

Một phiên bản F # của giải pháp Keith. Các danh sách là bất biến theo mặc định, vì vậy phiên bản này sẽ nhét toàn bộ hàm đệ quy vào một danh sách, trả về danh sách, từ đó các mục được trích xuất bằng for..dovòng lặp và a yield!. Tôi không thể tìm ra cách đảo ngược tiền tố một cách chính xác, vì vậy tôi chỉ gắn hậu tố vào bộ ba.

FYI, phương thức TryPude trả lại gấp đôi (bool,int).


2

Clojure - 480 ký tự

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

Đây là chương trình Clojure đầu tiên của tôi cũng như lần thử chơi Clojure đầu tiên của tôi, vì vậy, không cần phải nói, điều này không nên được coi là đại diện cho các giải pháp Clojure nói chung. Tôi chắc chắn rằng nó có thể được rút ngắn đáng kể, đặc biệt nếu phương pháp phân tích và xây dựng các hộp của Keith Randall ngay lập tức được thực hiện.


Man, một nửa nguồn này phải là khoảng trắng. Và bắt buộc như vậy :-). Tuy nhiên, thật thú vị và tôi tự hỏi liệu người ta sẽ thấy một biến thể Lisp giành được một mã golf ;-)
Joey

Tôi chắc chắn là có thể ... mặc dù như tôi đã nói, có lẽ tôi sẽ không phải là người làm điều đó.
Casey

2

C # - 472 470 426 422 398 ký tự

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

Đẹp. A goto! Nhân tiện, bạn có thể bỏ qua các dấu ngoặc đơn xung quanh các đối số lambda zvđưa nó xuống 421.
Joey

2

Scala - 475 ký tự

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 Ký tự

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
Phiên bản Ungolfed đã có trên github - github.com/paulduran/CodeGolf
Fatal

Tham gia với \nxuất hiện là đủ cuối cùng.
Joey

Loại bỏ giao diện giải phóng rất nhiều nhân vật, phần còn lại chủ yếu là chơi golf tiêu chuẩn. Có rất nhiều điều có thể được thực hiện ở đây, tôi hy vọng điều này có thể đạt được dưới 600.
Nick Larsen

Nick làm việc tốt. Tôi nghi ngờ giao diện là một chút quá mức, thành thật mà nói. một lá cờ đơn giản sẽ có hiệu lực trong tình huống này như bạn đã chỉ ra.
Gây tử vong vào

0

Pip , 89 byte (không cạnh tranh)

(Ngôn ngữ mới hơn thách thức. Ngoài ra, tôi không thể vượt qua APL.)

Mã là 87 byte, +2 cho -rncờ.

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

Hãy thử trực tuyến!

Hàm zxử lý mục đầu tiên của danh sách đầu vào ( g, được sao chép vào biến toàn cục iđể có sẵn trong các lệnh gọi hàm). Nếu đây là số n , nó tự gọi mình là n lần, đệm danh sách các dòng kết quả vào một hình chữ nhật đầy đủ, bọc từng dòng vào "| " " |", thêm .---.'---'dòng trước khi trả về danh sách mới. Nếu nó là một chuỗi, nó chỉ cần chuyển đổi nó thành một danh sách một mục và trả về nó. Kết quả cuối cùng được in tách dòng mới ( -ncờ). Thêm chi tiết có sẵn theo yêu cầu.


Tôi thường không gặp vấn đề với các ngôn ngữ mới hơn thách thức, đặc biệt khi xem xét rằng vấn đề không quá tầm thường đến nỗi một ngôn ngữ mới được tạo sẽ có các thao tác đặc biệt để giải quyết nó :-)
Joey

Điều này thất bại mẫu thứ tư.
Joey

0

Java (1369 ký tự bao gồm EOL)

Không thể để điều này mà không có triển khai Java. Java được cho là dài dòng hơn về sự chậm chạp của Python và Ruby, vì vậy tôi đã tìm kiếm một giải pháp đệ quy thanh lịch.

Ý tưởng là một Cây (Đồ thị) của các đối tượng (chuỗi và hộp), chứa nhau bắt đầu từ hộp "đầu". Khi bạn phân tích tuyến tính tệp đầu vào, bạn thêm chuỗi và hộp vào hộp "hiện tại" và trong khi bạn thêm chiều dài tối đa của vùng chứa được điều chỉnh. Khi một container đạt đến số lượng vật phẩm được xác định trước mà nó có thể giữ bạn quay lại container trước đó. Ở phần cuối của tệp đầu vào, bạn có một thùng chứa "đầu" đã được tính toán "maxLpm", vì vậy bạn chỉ cần gọi phương thức print () của nó.

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

Nó thực sự là một giải pháp thú vị để viết. Tôi thích câu hỏi rất nhiều. Như tôi đã đề cập trước đó, tôi đã tìm kiếm giải pháp thanh lịch không phải là cách tiếp cận tối giản, đáng buồn là Java không có bản in của Python "-" * 4 để tạo ra "----" :-)

Đây là phiên bản chưa được chỉnh sửa:

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
Bạn biết đấy, đây là một mã golf . Ít nhất bạn nên thử nhắm đến một giải pháp nhỏ . Elegance là tất cả tốt đẹp và tốt, nhưng không thực sự cần thiết cũng không muốn ở đây.
Joey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.