1P5 : 중첩 상자


53

이 작업은 제 1 회 정기 프리미어 프로그래밍 퍼즐 푸시의 일부입니다 .

다음 형식의 항목 계층 구조를 얻습니다.

2
Hat
1
Gloves

다음과 같이 상자에 넣어야합니다.

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

입력 형식에서 숫자는 숫자가 지정하는 항목 수만큼 상자를 시작합니다. 첫 번째 상자에는 두 개의 항목 (햇과 장갑이 들어있는 상자)이 있으며 두 번째 상자에는 장갑이라는 단일 항목 만 있습니다.

보시다시피 상자는 상자 안에 살 수 있습니다. 그리고 그들은 항상 반올림됩니다 ... (뾰족한 모서리는 상처의 위험이 있으며 우리는 그것을 원하지 않을 것입니다).

아래에는 사양이 제공하는 모든 작은 여유를 활용하려는 사람들에 대한 불쾌한 세부 사항이 있습니다. 스펙을 읽지 않아도 잘못된 솔루션을 제출할 이유가 없습니다. 끝에 테스트 스크립트와 몇 가지 테스트 사례가 있습니다.


사양

  • 상자는 다음 문자로 구성됩니다.

    • | (U + 007C)는 수직 모서리를 구성하는 데 사용됩니다.
    • - (U + 002D)는 수평 가장자리를 구성하는 데 사용됩니다.
    • ' (U + 0027)은 둥근 아래쪽 모서리입니다.
    • . (U + 002E)는 둥근 상단 모서리입니다.

    따라서 상자는 다음과 같습니다.

    .--.
    |  |
    '--'
    

    유니 코드에는 둥근 모서리와 적절한 상자 그리기 문자가 있지만이 작업은 ASCII로만 이루어집니다. 내가 유니 코드를 좋아하는 한, 2 ~ 10 년 사이에 아직 도착하지 않은 언어와 환경이 있다는 것을 알고 있습니다.

  • 상자에는 텍스트 또는 다른 항목 인 일련의 항목이 포함될 수 있습니다. 상자의 개별 항목은 위에서 아래로 렌더링됩니다. 따라서 시퀀스 A, B, C는 다음과 같이 렌더링됩니다.

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

    이것은 물론 텍스트와 같은 항목 인 중첩 상자에도 적용됩니다. 따라서 시퀀스 A, B, Box (C, Box (D, E)), F는 다음과 같이 렌더링됩니다.

    .-----------.
    | A         |
    | B         |
    | .-------. |
    | | C     | |
    | | .---. | |
    | | | D | | |
    | | | E | | |
    | | '---' | |
    | '-------' |
    | F         |
    '-----------'
    
  • 상자는 내용에 따라 크기를 조정하고 중첩 된 상자는 항상 부모의 크기로 확장됩니다. 내용 앞뒤에 항상 공백이 있으므로 텍스트 상자 나 중첩 상자가 바깥 상자 가장자리에 너무 가까이 있지 않습니다. 요컨대, 다음은 잘못되었습니다.

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

    그리고 다음이 맞습니다.

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

    훨씬 더 좋아 보인다 :-)

  • 텍스트 항목 (아래 입력 참조)을 정확하게 재현해야합니다.

  • 항상 최상위 수준의 단일 상자가 있습니다 (XML 참조). 그러나 한 상자에 여러 개의 다른 상자가 포함될 수 있습니다.

입력

  • 입력은 표준 입력에 제공됩니다. 더 쉬운 테스트를 위해 파일에서 리디렉션 될 수 있습니다.

  • 입력은 줄 단위로 제공되며 각 줄은 현재 상자에 넣거나 새 상자를 여는 텍스트 항목을 나타냅니다.

  • 모든 줄은 줄 바꿈으로 종료됩니다.

  • 텍스트 항목은 숫자로 구성되지 않은 줄로 표시됩니다 (아래 참조). 텍스트는 알파벳 문자, 공백 및 문장 부호 ( .,-'"?!())를 사용합니다. 텍스트는 공백으로 시작하거나 끝나지 않으며 항상 하나 이상의 문자를 갖습니다.

  • 상자는 숫자가있는 한 줄로 시작합니다. 숫자는 상자의 크기, 즉 상자에 넣은 다음 항목의 수를 나타냅니다.

    2
    A
    B
    

    두 개의 텍스트 항목이있는 상자를 생성합니다.

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

    상자에는 항상 하나 이상의 항목이 포함됩니다.

  • 상자의 끝은 명시 적으로 선으로 표시되지 않습니다. 대신 지정된 수의 항목을 넣은 후 상자가 암시 적으로 닫힙니다.

  • 상자는 항목 수에 관계없이 항상 단일 항목입니다. 예 :

    3
    A
    4
    a
    b
    c
    d
    B
    

    세 개의 항목이있는 상자가 나오고 두 번째는 네 개의 항목이있는 다른 상자입니다.

    중첩은 상자가 단일 항목이라는 사실에도 영향을 미치지 않습니다.

제한

  • 최대 중첩 수준은 5 입니다. 즉, 서로 안에 최대 5 개의 상자가 있습니다. 여기에는 가장 바깥 쪽이 포함됩니다.

  • 상자 당 최대 10 개의 품목이 있습니다.

  • 텍스트 항목의 최대 길이는 100 자입니다.

산출

  • 출력은 위에서 설명한 규칙에 따라 모든 포함 및 중첩 항목을 포함하는 렌더링 된 상자입니다.
  • 출력은 표준 출력으로 제공되어야하며 정확하게 일치해야합니다. 선행 또는 후행 공백은 허용되지 않습니다.
  • 각 줄은 마지막 줄을 포함하여 줄 바꿈으로 끝나야합니다.

승리 조건

  • 가장 짧은 코드가 승리합니다 (즉, 허용 된 답변을 얻음).

샘플 입력 1

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

샘플 출력 1

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

샘플 입력 2

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

샘플 출력 2

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

샘플 입력 3

1
1
1
1
1
Extreme nesting Part Two

샘플 출력 3

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

샘플 입력 4

3
Foo
2
Bar
Baz
2
Gak
1
Another foo?

샘플 출력 4

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

테스트 스크립트

우리 ( Ventero 와 나)는 테스트 스크립트를 준비했을 때 세부 정보를 올바르게 얻는 것이 어려울 수 있으므로 솔루션이 올바른지 확인하기 위해 솔루션을 실행할 수 있습니다. PowerShell 스크립트bash 스크립트 모두로 사용할 수 있습니다 . 호출은 다음과 같습니다 <test-script> <program invocation>.

업데이트 : 테스트 스크립트가 업데이트되었습니다. 내가 정의한 한계를 따르지 않는 여러 테스트 사례가있었습니다. PowerShell 테스트 스크립트는 결과를 확인하기 위해 대소 문자 구분을 사용하지 않았습니다. 지금은 모든 것이 잘되기를 바랍니다. 마지막 사례는 현재 상당히 많지만 테스트 사례의 수는 156으로 줄었습니다.

업데이트 2 : 테스트 케이스 생성기를 업로드했습니다 . .NET 2 런타임을 대상으로하는 C #으로 작성되었습니다 . 모노에서 실행됩니다. 사람들이 구현을 테스트하는 데 도움이 될 수 있습니다. 작업의 한계를 고려한 결정적인 최악의 경우 :

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

이것은 가장 안쪽 레벨까지 상자 만 생성하며 상자 당 최대 항목 수와 최대 텍스트 항목 길이를 모두 사용합니다. 그러나이 테스트 케이스는 테스트 스크립트에 포함시키지 않았습니다. 왜냐하면 상당히 크고 출력이 훨씬 큽니다.

업데이트 3 : 스크립트의 줄 끝과 솔루션이 인쇄 된 줄 끝에 따라 오류가 발생하기 쉬운 PowerShell 테스트 스크립트를 업데이트했습니다. 이제 두 가지 모두에 대해 불가지론해야합니다. 혼란을 드려 죄송합니다.


상자의 크기를 내용에 맞게 조정해야한다고 말합니다. 그러나 마지막 예제에서 첫 번째 내부 상자는 외부 상자의 크기를 조정합니다. 그렇다면 중첩 된 상자의 크기는 어떻게됩니까?
Juan

@ JUAN : 그것을 잡아 주셔서 감사합니다. 그런 일이 여전히 일어나는 것처럼 놀라운. 편집 :-)
Joey

1
@Joey 옛날이지만 좋은 사람. 다행히도 일부 새로운 사용자가 구체적이고 구체적으로 작성된 좋은 질문을 작성하도록 영감을 줄 수 있기를 바랍니다. :-)
Gareth

@Gareth, 나는 더 많은 것을 다시 쓸 시간을 찾기 위해 분명히 노력해야합니다. 그러나 잘 지정된 질문, 테스트 케이스, 참조 구현 및 물건 (일이 나는 시간을) 경쟁에 필수적인 고려,하지만보기는 많은 공유되지 않습니다). uni : D
Joey

답변:


2

GolfScript, 125 자

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

Keith의 솔루션 과 유사한 접근 방식을 사용합니다 .


26

파이썬, 204 자

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]

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]

우와, 그것은 빠르다. 흥미로운 아이디어가 P있습니다.
Joey

와우 이것은 흥미 롭습니다. ungolfed 버전을 게시 할 수 있습니까? 평가 비트의 작동 방식을 이해하고 싶습니다. 훗, 내 ungolfed 파이썬 솔루션은 1500 + 문자입니다 :( 나는 완전히 다른 (비효율적) 접근을하지만.
케이시

@Casey : eval은 루프를위한 골프 단축키 일 뿐이며 기본이 아닙니다. 나는 초에 ungolfed 버전을 게시합니다 ...
Keith Randall

13

루비 1.9, 174 자

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}

Keith의 솔루션 과 다소 유사합니다 .


6

APL (78)

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


솔루션을 테스트하기 위해 tio.run에서 실행할 수 없습니다. 그렇지 않으면 허용 된 답변도 전환합니다.
Joey

5

파이썬 - 355 개 314 259 문자

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

거의 100 문자 감소, 좋은 직업.
Casey

5

루비 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 문자

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

와 컴파일 gcc -std=gnu99 -w file.c

Keith의 버전에 가깝지는 않지만 좋은 C입니다.


160 개의 테스트 중 159 개만 통과합니다.
Joey

아야. 지금은 괜찮다고 생각합니다. 극단적 인 경우 \ 0에 공간을 할당하는 것을 잊고있었습니다.
esneider

테스트 # 142는 여전히 실패합니다. 그건 그렇고, 실제 극단적 인 경우는 10 MiB 입력과 78 MiB 출력을 가지고 있기 때문에 존재하지 않습니다. 나는 테스트 스크립트가 그렇게 큰 것을 원하지 않았다 ;-)
Joey

이상하게, 나는 얻는다 160/160 passed(나는 100 개의 문자열을 의미한다, 그것은 어쨌든 존재하지 않는다)
esneider

흠, 이상해 x64 FreeBSD 8.2-RELEASE #5: Sun Feb 27 10:40:25 CET 2011와 함께 gcc version 4.2.1 20070719 [FreeBSD]여기에. 나는 160에 대한 당신의 말씀을 받아 들일 것입니다 :-). 그리고 실제로는 100 자로 된 테스트 케이스가 있어야합니다 (테스트 143–147).
Joey

4

매우 기능적인 파이썬, 460 자

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

흠, 이것은 |문자가 올바르게 배치되지 않은 저에게는 작동하지 않는 것 같습니다 . 그것은 내 파이썬 솔루션과 매우 유사합니다
Casey

2
실제로 테스트 사례를 통과하지 않습니다. eordano : 우리는 아무도 더 이상 틀린 대답을 제출하지 않도록 포함 시켰습니다.
Joey

1
이전 버전의 코드를 붙여 넣은 것 같습니다. 지금 작동해야합니다. 비전문가 인 것에 대해 죄송합니다.
eordano

나를 위해 작동합니다! 좋은 해결책, 나는 기능적인 접근 방식을 좋아합니다.
Casey

실제로 지금 작동합니다.
Joey

4

하스켈, 297 자

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

골프를 치는 동안이 방법은 매우 간단합니다. 사용 가능한 메모리 만 제한됩니다.


4

C # -1005 8852852782 문자

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

나는 그것이 향상 될 수 있다고 확신하기 때문에 이것을 다시 한번 볼 필요가 있지만, 이것은 나의 번째 단계입니다.

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, 그래, 나는 다시 한번 더 그것을 거쳐야한다. 논리를 가지고 놀고 그것을 삭감해야합니다.
Rebecca Chernoff

나는 C에 익숙하지 않지만 JS에서는 다음과 같이 여러 var 문을 하나로 결합 할 수 있습니다 var a = 1, b = 2, c = 3;. C에서도 같은 일을 할 수 없습니까?
nyuszika7 시간

2
@ Nyuszika7H, 이것은 C가 아니라 C # var입니다. 암시 적 진술을 결합 할 수는 없습니다 . 사용하여 Joey와 같은 명시 적 유형이있는 경우에만 결합 할 수 있습니다 string b="",e="".
Rebecca Chernoff

@RebeccaChernoff : 나는 다른 사람들의 대답, 689에서 일했습니다.
Nick Larsen

@NickLarsen, 좋았지 만 보이지 않습니다. 질문 : 아직 시간이 필요합니다. 이것은 논리에 대한 나의 첫 걸음이었습니다. 논리에 대해 더 똑똑 할 수있는 장소가 있다고 확신합니다.주의를 기울일 시간이 필요합니다.
Rebecca Chernoff

4

PHP, 403 개 388 306 문자

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

언 골프 드 :

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

나는 Keith로부터 접두사-아이디어를 빌렸다. (이것이 전혀 허용 되는가?) 그렇지 않으면 이것은 원본과 거의 비슷하다. 여전히 300 이하로 떨어질 수 없었습니다. 앞으로.


2
글쎄, 코드는 모든 경우에 공개되어 있으므로 빌리는 아이디어가 허용되고 심지어 장려됩니다. 나는 또한이 사이트가 다른 비슷한 사이트와 차별화되는 것이라고 생각합니다. gnibbler가 지적했듯이 우리는 동시에 경쟁하고 협력합니다 .
Joey

3

PHP, 806 개 769 721 653 619 문자

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

언 골프 버전 :

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

한 글자 대신 두 글자로 된 함수 이름을 사용하는 이유는 무엇입니까?
Lowjacker

@Lowkacler : 잘 잡습니다. 여전히 최적화해야 할 것이 있습니다. 나는 축소기를 가지고 있지 않았으므로 수동으로했습니다. 또한 개선해야 할 부분 (코드 축소, 축소)에 대한 몇 가지 아이디어가 있으므로 나중에 개정 버전을 게시 할 것입니다.
MicE

1
우선 <?, 처음에는 달리기조차 빠졌습니다 . 그런 다음 테스트 케이스 의 모든 텍스트 항목 의 최대 길이를 가장 안쪽 상자의 너비로 사용합니다. 이 코드는 118 개의 테스트 사례 (Linux 및 FreeBSD에서 테스트) 만 통과합니다. PowerShell 스크립트에서 어떻게 실행되지 않았는지 잘 모르겠지만 :-( powershell -noprofile -file test.ps1 php boxes.php실제로 작동하도록 호출 하지만 Windows 컴퓨터에는 테스트 할 PHP가 없습니다.
Joey

최신 bash 스크립트를 사용하여 내 상자에서 이것을 테스트했으며 118/156을 얻었습니다. 나는 출력을 요점
Juan

1
듣기 좋네요 :). 그것이 처음에는 한 줄 출력을위한 테스트 스크립트를 작성하기 위해 얻은 것입니다. ;-)
Joey

3

자바 - 681 개 668 문자

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

Keith Randall의 Python 코드와 기본적으로 동일한 방법

언 골프 버전 :

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

때마다 하나의 공간을 제거 할 수 있다고 생각합니다 throws.
Joey

예! 또한 몇 문자를 더 배출했습니다. (각 줄이 줄 바꿈 문자로 끝나는 것으로 가정 할 수 있음, 중복 break;)
Greg Schueler

아마도 기교 수 char이상 아스키 코드를보고 비교를 ...하지만 난 휴가를위한 준비 가야
그렉 Schueler

3

-200 199 자

Keith Randall의 Python (좋은 디자인, Keith)과 동일한 알고리즘이지만이 Perl에서 조금 더 콤팩트합니다.

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

1
$_@_@_달러 기호를 쫓는 사람처럼 보이는
ajax333221

3

F #-341 자

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)

Keith 솔루션의 F # 버전. 리스트는 기본적으로 불변이므로,이 버전은 전체 재귀 함수를리스트에 채우고 for..do루프와 a를 사용하여 아이템이 추출되는리스트를 리턴합니다 yield!. 접두사를 간결하게 뒤집는 방법을 찾을 수 없으므로 서 픽스를 트리플에 붙였습니다.

참고로 TryParse 메서드는 double을 반환합니다 (bool,int).


2

클로저-480 자

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

이것은 첫 번째 Clojure 프로그램이자 첫 번째 Clojure 골프 시도이므로 반드시 Clojure 솔루션을 대표하는 것으로 간주해서는 안됩니다. 특히 Keith Randall의 상자 구문 분석 및 빌드 방법 이 구현 된 경우 크게 단축 될 수 있다고 확신합니다 .


이 소스의 절반은 공백이어야합니다. 그리고 mandatorily 그래서 :-). 흥미롭지 만 Lisp 변형이 코드 골프에서 이길 지 궁금합니다 ;-)
Joey

나는 그것이 가능하다고 확신하지만 ... 내가 말했듯이, 나는 그것을하는 사람이 아닐 것입니다.
Casey

2

C # -472470426422 398 자

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

좋은. A goto! 그건 그렇고, 당신은 람다 인수 주위에 괄호를 생략 할 수 있습니다 zv(421)이 아래로 데리고
조이

2

스칼라-475 자

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 689671634 문자

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
Ungolfed 버전은 github에 있습니다 -github.com/paulduran/CodeGolf
Fatal

에 합류 \n하면 결국 충분합니다.
Joey

인터페이스를 없애고 많은 캐릭터를 확보했으며 나머지는 대부분 표준 골프였습니다. 여기에서 할 수있는 일이 훨씬 더
Nick Larsen

잘 했어 닉. 솔직히 말해서 인터페이스가 약간 과도하다고 생각했습니다. u가 보여준 것처럼이 상황에서 간단한 플래그로 충분했을 것입니다.
치명적인

0

, 89 바이트 (비경쟁)

(언어는 도전보다 새로운 언어입니다. 또한 APL을 능가 할 수 없었습니다.)

코드는 87 바이트, -rn플래그는 +2입니다 .

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

온라인으로 사용해보십시오!

함수 z는 입력 목록의 첫 번째 항목을 처리합니다 ( g, i함수 호출 내에서 사용 가능하도록 전역 변수로 복사 됨 ). 이 숫자 인 경우 n은 , 그것은 자신을 재귀 적으로 호출 N 시간은 전체 사각형 라인의 결과 목록을 패드의 각 줄을 래핑 "| " " |"하고, 추가 .---.하고 '---'새 목록을 반환하기 전에 라인. 문자열 인 경우 단순히 해당 항목을 하나의 항목 목록으로 변환하여 반환합니다. 최종 결과는 개행으로 분리 된 ( -n플래그)로 인쇄 됩니다. 요청시 자세한 내용을 확인할 수 있습니다.


나는 일반적으로 문제보다 새로운 언어에 문제가 없다. 특히 문제가 그리 사소하지 않다는 점을 고려할 때, 새로 작성된 언어는이를 해결하기 위해 특별히 조작 할 수있다
Joey

이것은 네 번째 샘플에 실패합니다.
Joey

0

Java (EOL 포함 1369 자)

Java 구현 없이는 이것을 남겨 둘 수 없습니다. Java는 Python과 Ruby의 매끄러운 것보다 더 장황해야하므로 우아하고 재귀적인 솔루션을 찾았습니다.

아이디어는 "머리"상자에서 시작하여 서로를 포함하는 객체 (문자열 및 상자)의 트리 (그래프)입니다. 입력 파일을 선형으로 구문 분석 할 때 문자열과 상자를 "현재"상자에 추가하고 컨테이너의 최대 길이를 추가하는 동안 조정됩니다. 컨테이너가 사전 정의 된 항목의 양에 도달하면 이전 컨테이너로 역 추적 할 수 있습니다. 입력 파일의 끝에 이미 "maxLength"가 계산 된 "head"컨테이너가 있으므로 간단히 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,"");}}

정말 재미있는 솔루션입니다. 나는 그 질문을 많이 좋아했다. 앞에서 언급했듯이 미니멀리즘이 아닌 솔루션 우아함을 찾았습니다. 슬프게도 Java에는 "----":-)를 생성하는 Python의 인쇄 "-"* 4가 없습니다.

ungolfed 버전은 다음과 같습니다.

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
알다시피, 이것은 코드 골프 입니다. 최소한 작은 솔루션을 목표로 노력해야 합니다. 우아함은 좋고 훌륭하지만 실제로는 여기에서 필요하거나 원하지 않습니다.
Joey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.