1P5: İç içe geçmiş kutular


53

Bu görev, Birinci Periyodik Premier Programlama Bilmece Baskısının bir parçasıdır .

Aşağıdaki biçimde öğelerin sıradüzenini alırsınız:

2
Hat
1
Gloves

hangi gibi kutulara koymak gerekir:

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

Girdi biçiminde sayılar, sayının belirttiği sayıda öğe içeren bir kutu başlatır. İlk kutunun içinde iki eşya vardır (Şapka ve Eldivenleri içeren kutu), ikincisi sadece tek bir parça içerir - eldivenler.

Görülebileceği gibi, kutular da kutular içinde yaşayabilir. Ve her zaman yuvarlanırlar ... bir çeşit (sivri köşeler bir yara tehlikesidir ve biz bunu istemeyiz).

Aşağıda, şartnamenin verdiği her küçük parçayı kullanmak isteyenler için kötü detaylar var. Dikkat edin, spec okumayan yanlış çözümler sunmak için hiçbir bahane değildir. En sonunda bir test senaryosu ve birkaç test senaryosu var.


Şartname

  • Kutular aşağıdaki karakterlerden oluşur:

    • | (U + 007C) dikey kenarları oluşturmak için kullanılır.
    • - Yatay kenarları oluşturmak için (U + 002D) kullanılır.
    • ' (U + 0027) yuvarlak alt köşelerdir.
    • . (U + 002E) yuvarlak üst köşelerdir.

    Bir kutu bu nedenle şöyle görünür:

    .--.
    |  |
    '--'
    

    Unicode'un ayrıca yuvarlak köşeleri ve uygun kutu çizim karakterleri olmasına rağmen, bu görevin yalnızca ASCII'de olduğunu unutmayın. Unicode'u sevdiğim kadarıyla, son on yılda, tam olarak varılmayan dillerin ve ortamların olduğunu fark ediyorum.

  • Kutular, metin veya diğer öğelerden oluşan bir dizi dizisi içerebilir. Kutudaki tek tek öğeler yukarıdan aşağıya doğru oluşturulur. Böylece A, B, C dizileri aşağıdaki gibi işler:

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

    Elbette bu, metin gibi bir öğe olan iç içe geçmiş kutular için de geçerlidir. Böylece A, B, Kutu (C, Kutu (D, E)), F dizisi aşağıdaki gibi olacaktır:

    .-----------.
    | A         |
    | B         |
    | .-------. |
    | | C     | |
    | | .---. | |
    | | | D | | |
    | | | E | | |
    | | '---' | |
    | '-------' |
    | F         |
    '-----------'
    
  • Kutular boyutlarını içeriğe göre ayarlar ve iç içe geçmiş kutular her zaman ana öğelerinin boyutuna genişletilir. İçerikten önce ve sonra bir boşluk vardır, böylece ne metin ne de iç içe geçmiş kutular dış kutunun kenarına çok yakın olmaz. Kısacası, aşağıdaki yanlış:

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

    Ve aşağıdaki doğrudur:

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

    Çok daha güzel görünüyor :-)

  • Metin öğeleri (aşağıdaki Girişe bakınız) tam olarak çoğaltılmalıdır.

  • Her zaman tek bir üst seviye kutu vardır (cf. XML). Ancak, bir kutu başka birkaç kutu içerebilir.

Giriş

  • Giriş standart girişte verilir; Daha kolay bir test için muhtemelen bir dosyadan yönlendirildi.

  • Girdi satır şeklinde verilir; her satır geçerli kutuya koymak için bir metin öğesini temsil eder veya yeni bir kutu açar.

  • Her satır bir satır sonu ile sonlanır.

  • Metin öğeleri, sayı içermeyen bir satırla işaretlenmiştir (aşağıya bakınız). Metin alfabetik karakterler, boşluk ve noktalama işaretleri ( .,-'"?!()) kullanır. Metin boşlukla başlamaz veya bitmez ve her zaman en az bir karakter olur.

  • Bir kutu içinde bir sayı bulunan tek bir satırla başlar. Sayı, kutunun boyutunu, yani içine konulan aşağıdaki öğelerin sayısını söyler:

    2
    A
    B
    

    iki metin öğeli bir kutu verir:

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

    Bir kutu her zaman en az bir öğe içerecektir.

  • Kutuların sonu açıkça bir çizgiyle işaretlenmez; bunun yerine kutular, belirtilen sayıda öğenin içine koyulduktan sonra örtük olarak kapatılır.

  • Bir kutu, içinde kaç tane öğe olduğuna bakılmaksızın, her zaman yalnızca bir öğedir. Örneğin

    3
    A
    4
    a
    b
    c
    d
    B
    

    ikincisi dört maddeli bir başka kutu olan üç maddeli bir kutu üretecektir.

    Yuvalama ayrıca bir kutunun yalnızca tek bir öğe olduğu gerçeğini etkilemez.

Sınırları

  • Maksimum iç içe geçme seviyesi beş . Yani birbirlerinin içinde en fazla beş kutu var. Bu en dıştaki olanı içerir.

  • Kutu başına en fazla on öğe var.

  • Metin öğelerinin maksimum uzunluğu 100 karakterdir.

Çıktı

  • Çıktı, yukarıda belirtilen kurallara göre tüm içeren ve iç içe geçen öğeleri içeren işlenmiş kutudur.
  • Çıktı standart çıktıda verilmelidir ve tam olarak eşleşmelidir. Baştaki veya sondaki boşluklara izin verilmez.
  • Her satır, sonuncusu da dahil olmak üzere bir satır sonu ile sonlandırılmalıdır.

Kazanma koşulu

  • En kısa kod kazanır (yani kabul edilen cevabı alır).

Örnek giriş 1

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

Örnek çıktı 1

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

Örnek giriş 2

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

Örnek çıktı 2

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

Örnek giriş 3

1
1
1
1
1
Extreme nesting Part Two

Örnek çıktı 3

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

Örnek giriş 4

3
Foo
2
Bar
Baz
2
Gak
1
Another foo?

Örnek çıktı 4

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

Test Komut Dosyası

Doğru bilgileri almak bazen zor olabileceğinden ( Ventero ve ben) doğru olup olmadığını kontrol etmek için çözümünüzü çalıştırabileceğiniz bir test senaryosu hazırladık. Bu bir hem de kullanılabilir PowerShell komut dosyası ve bir bash betiği . Çağırma geçerli: <test-script> <program invocation>.

GÜNCELLEME: Test komut dosyaları güncellendi; Tanımladığım sınırlara uymayan birkaç test vakası vardı. PowerShell test komut dosyası, sonucu kontrol etmek için büyük / küçük harfe duyarlı karşılaştırma kullanmamıştır. Umarım şimdi her şey yolundadır. Sonuncusu oldukça büyük olmasına rağmen test vakalarının sayısı 156'ya düşürüldü.

GÜNCELLEME 2: Test çantası oluşturucumu yükledim . .NET 2 çalışma zamanını hedef alan C # ile yazılmış . Mono'da çalışıyor. İnsanların uygulamalarını test etmelerine yardımcı olabilir. Kesin bir kötü durum olarak görevdeki limitleri göz önünde bulundurarak deneyebilirsiniz:

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

yalnızca en iç düzeye kadar olan kutuları üretecek ve kutu başına maksimum öğe sayısını ve maksimum metin öğesi uzunluğunu kullanacaktır. Bu test senaryosunu test betiğine dahil etmedim, çünkü oldukça büyük ve çıktı daha büyük.

GÜNCELLEME 3: Satır sonlarının kodda nasıl olduğuna ve çözümün hangi satırda biteceğine bağlı olarak hata atmaya yatkın olan PowerShell test komut dosyasını güncelledim. Şimdi her ikisine de agnostik olmalı. Karışıklık için tekrar özür dilerim.


Kutuların boyutlarını içeriklerine göre ayarlaması gerektiğini söylüyorsunuz. Yine de son örnekte, ilk iç kutu, boyutunu dış kutuya ayarlar. Peki, iç içe kutu nasıl boyutlandırılır?
Juan,

@Juan: Onu yakaladığın için teşekkürler. Hala olanlar gibi kayan şaşırtıcı. Düzenlendi :-)
Joey

1
@Joey Bir oldy ama bir elveda. Umarım, bazı yeni kullanıcılarımıza iyi, iyi tanımlanmış sorular yazmak için ilham verebilir. :-)
Gareth

@Gareth, kesinlikle daha fazlasını yazmak için zaman bulmaya çalışmalıyım. Ancak iyi tanımlanmış bir soru, test durumları, referans uygulaması ve eşyalar ( bir yarışma için gerekli olduğunu düşündüğüm şeyler , ancak bu görüş pek çok kişi tarafından paylaşılmıyor;) zaman alıyor. Üniversitedeyken çok daha kolaydı: D
Joey

Yanıtlar:


2

GolfScript, 125 karakter

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

Keith'in çözümü gibi benzer bir yaklaşım kullanmak .


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]

Pher biri bir satır öneki / soneki (sonek öneki ters) olan bir üçlü listesi, bazı satır metni ve bir satır dolgusu karakteri döndürür. Tüm üçlüleri hesapladıktan sonra, tüm çizgileri aynı uzunlukta yapmak için doğru sayıda dolgu karakteri kullanılarak yazdırılırlar.

Ungolfed versiyonu:

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, bu hızlıydı. Ve Porada ilginç bir fikir .
Joey

Vay, gerçekten. Bu ilginç, unungolfed versiyonunu gönderebilir misin? Eval bit'in nasıl çalıştığını anlamak isterim. Heh, ungolfed python çözümüm 1500+ karakter :( Tamamen farklı (ve verimsiz) bir yaklaşım benimsemeye rağmen
Casey

@Casey: eval sadece bir döngü için golf kısayolu, bu temel değil. Bir saniye ungolfed versiyonunu göndereceğim ...
Keith Randall

13

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

Keith'in çözümüne biraz benziyor .


6

APL (78)

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

5
Bu ne ben bile
Nowayz

Çözümü test etmek için bunu tio.run üzerinde çalıştıramam. Aksi takdirde kabul edilen cevabı da değiştiririm.
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

neredeyse 100 karakter azaltma, iyi iş.
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 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);}

İle derleyin gcc -std=gnu99 -w file.c

Keith'in versiyonuna bile yakın değil, ama hey, bu iyi bir şey C


Buradaki 160 testten sadece 159'unu geçiyor.
Joey,

Ahh. Bence artık sorun değil. Aşırı durumda 0 için yer ayırmayı unutuyordum.
esneider,

Hala aynı görünüyor, Test # 142 başarısız oluyor. Bu arada, gerçek aşırı durum 10 MiB girişi ve 78 MiB çıkışı olduğu için bile mevcut değil. Test senaryosunun o kadar büyük olmasını istemedim ;-)
Joey

garip, alıyorum 160/160 passed(zaten bulunmayan 100 karakterlik bir dizi demek
istedim

Hm, garip. burada x64 FreeBSD 8.2-RELEASE #5: Sun Feb 27 10:40:25 CET 2011ile gcc version 4.2.1 20070719 [FreeBSD]. 160 için sözünüzü alacağım, sonra :-). Ve aslında 100 karakterden oluşan bir test vakası olmalıdır (Test 143-147).
Joey,

4

çok fonksiyonel python, 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))

Hmm, bu benim için işe yaramıyor gibi görünüyor |karakterlerin doğru aralıklı değil. Python çözümüme çok benziyor
Casey

2
Nitekim, test durumlarının hiçbirini geçmiyor. eordano: Bunları ekledik, böylece hiç kimse artık yanlış olan cevapları sunmayacaktı.
Joey,

1
Sanırım kodun eski bir versiyonunu yapıştırdım. Şimdi çalışmalıyım. Profesyonel olmadığım için üzgünüm.
eordano

Benim için çalışıyor! Güzel çözüm, işlevsel yaklaşımı seviyorum.
Casey,

Gerçekten, şimdi çalışıyor.
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

Golf yaparken, yöntem oldukça açık. Sadece limitler kullanılabilir hafıza.


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

İyileştirilebileceğinden emin olduğum için buna bir daha bakmam gerekiyor, ancak bu benim ilk girişim .

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, evet, kesinlikle tekrardan geçmem gerekiyor. Ayrıca onu denemek ve kesmek için mantık ile oynamak gerekir.
Rebecca Chernoff

Ben C aşina değilim ama JS, böyle, birine birden var ifadeleri birleştirebilirsiniz: var a = 1, b = 2, c = 3;. C de aynı şeyi yapamaz mısın?
nyuszika7h

2
@ Nyuszika7H, bu C #, C değil. Öyle örtük varifadeleri birleştiremezsiniz . Sadece Joey'nin bahsettiği gibi açık bir türe sahiplerse birleştirebilirsiniz string b="",e="".
Rebecca Chernoff

@ReccaChernoff: Şimdi 689, diğer adamların cevap üzerinde çalıştım.
Nick Larsen

@ NickLarsen, güzel - ama bakmıyorum. S: Madende ilerlemek için hala biraz zamana ihtiyacım var. Bu benim ilk mantığımdı, mantık hakkında daha akıllı olabileceğim yerler olduğuna eminim, sadece dikkat etmek için zamana ihtiyacım var.
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."'","-");}

Ungolfed:

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

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

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

Önek fikrini Keith'den ödünç aldım (buna izin veriliyor mu?), Aksi takdirde bu orijinal. Hala 300'ün altına inemedi. Buna sıkışıp kaldım. İleriye.


2
Kod burada her durumda halka açıktır, bu nedenle ödünç alma fikirlerine izin verilir ve hatta teşvik edilir. Ayrıca bu siteyi diğerlerinden benzerlerinden ayıran bir şey olduğunu düşünüyorum. Gnibbler'ın belirttiği gibi , aynı anda hem rekabet ediyoruz hem de işbirliği yapıyoruz .
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);?>

Ungolfed versiyonu:

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

Neden bir harf yerine iki harfli işlev adları kullanıyorsunuz?
Lowjacker

@Lowkacler: iyi yakalama, hala optimize etmem gereken bir şey var. Eldeki herhangi bir minifier yoktu, bu yüzden manuel olarak yaptım. Ayrıca, neyin geliştirileceği hakkında (codewise, küçültme değil) birkaç fikrim var, bu yüzden daha sonra gözden geçirilmiş bir versiyonunu yayınlayacağım.
MicE

1
Her şeyden önce, bu <?bile çalıştırmak için başlangıçta bir eksik . Öyleyse , bir test senaryosundaki tüm metin öğelerinin maksimum uzunluğunu en içteki kutunun genişliği olarak kullanıyorsunuz. Bu kod yalnızca 118 test senaryosundan geçer (Linux ve FreeBSD'de test edilmiştir). powershell -noprofile -file test.ps1 php boxes.phpAncak, çalışmaması gereken PowerShell betiğine ne yaptığınız hakkında hiçbir fikrim yok :-(. Aslında çalışması gerektiği gibi çağırmak . Ama Windows makinemde test etmek için PHP'm yok.
Joey

Bunu en son bash betiğini kullanarak kutumda test ettim, 118/156. Çıktıyı bir yumruk
Juan

1
Duymak güzel :). Başlangıçta tek satırlık çıktı için tasarlanmış bir test komut dosyası yazdığım için bu ;-)
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;}}

aslında Keith Randall'ın Python kodu ile aynı yöntem

Ungolfed versiyonu:

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

Her seferinde bir yerden kurtulabileceğinizi düşünüyorum throws.
Joey

Evet! ayrıca birkaç tane daha karakter çıkardı. (her satırın newline char, gereksiz ile sonlandırıldığını varsayabilir break;)
Greg Schueler

Muhtemelen daha charuzun süre ascii kodlarına bakarak karşılaştırmaları finesse olabilir ... ama tatil için hazırlanmalıyım
Greg Schueler 30:11

3

Perl - 200 199 karakter

Keith Randall'ın Python'u ile aynı algoritma (güzel tasarım, Keith), fakat bu Perl'de biraz daha küçük.

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
$_@_@_dolar işareti kovalayan biri gibi görünüyor
ajax333221 27:12

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)

Keith'in çözümünün bir F # versiyonu. Listeler varsayılan olarak değiştirilemez, bu nedenle bu sürüm tüm özyinelemeli işlevi bir listeye yerleştirir, öğelerin for..dodöngü ve a kullanılarak çıkartıldığı listeyi döndürür yield!. Öneki kesin olarak tersine çevirmenin bir yolunu bulamadım, bu yüzden sadece son eki üçe ekledim.

Bilginize, TryParse yöntemi bir çift döndürür (bool,int).


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

Bu benim ilk Clojure programım ve ilk Clojure golf girişimim, bu yüzden, söylemeye gerek yok, genel olarak Clojure çözümlerinin temsilcisi olarak alınmamalıdır. Eminim, özellikle de Keith Randall'ın kutuları bir seferde ayrıştırma ve inşa etme yöntemi uygulandıysa , önemli ölçüde kısaltılabilir .


Dostum, bu kaynağın yarısı boşluk olmalı. Ve zorunlu olarak çok :-). İlginç, yine de, bir Lisp varyantının bir golf kodunu kazanıp kazanamayacağını merak ediyorum ;-)
Joey

Eminim mümkün ... dediğim gibi, muhtemelen yapacak olan ben olmayacağım.
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(' ','-')));}}

Güzel. A goto! Bu arada, lambda argümanlar etrafında parantez atlayabilirsiniz zve v421. Bu aşağı getirerek,
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}

1

C # 1198 1156 1142 689 671 634 Karakterler

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 versiyonu github'da - github.com/paulduran/CodeGolf
Fatal

İle katılmak \nsonunda yeterli olacaktır.
Joey

Arayüzden kurtulmak birçok karakteri serbest bıraktı, gerisi çoğunlukla standart golf oynuyordu. Burada yapılabilecek daha çok şey var, bunun 600'ün altına düşmesini beklerdim.
Nick Larsen

İyi işti Nick. Arayüzün dürüst olmak gerekirse biraz fazlaca olduğundan şüphelendim. Bu durumda, gösterdiğiniz gibi basit bir bayrak yeterli olacaktır.
Ölümcül

0

Pip , 89 bayt (rekabet etmeyen)

(Dil zorluktan daha yeni. Ayrıca, APL'yi tamamen geçemedim.)

Kod 87 bayt, -rnbayraklar için + 2'dir.

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

Çevrimiçi deneyin!

İşlev z, giriş listesinin ilk öğesini işler ( işlev çağrıları içinde kullanılabilir olması için ggenel değişkene kopyalanır i). Eğer bu sayı n ise , n kere tekrar eder, satırların tam listesini bir dikdörtgene doldurur, her bir satırı sarar ve yeni listeyi döndürmeden önce "| " " |"ekler .---.ve '---'satırlar ekler . Bir dizge ise, onu sadece bir maddelik listeye dönüştürür ve geri döndürür. Nihai sonuç, yeni satıra ayrılmış ( -nbayrak) yazdırılır . İstek üzerine daha fazla detay mevcuttur.


Genelde, sorundan daha yeni olan dillerle ilgili bir sorunum yok, özellikle de sorunun yeni oluşturulan bir dilin özellikle sorunu çözmek için gerekli işlemleri yapması kadar önemsiz olmadığını göz önünde bulundurarak :-)
Joey

Bu dördüncü örnekte başarısız olur.
Joey

0

Java (1369 karakter, EOL'ler dahil)

Java uygulaması olmadan bu bırakılamadı. Java'nın Python ve Ruby'nin kaymalarından daha ayrıntılı olması gerekiyordu, bu yüzden zarif ve özyineli bir çözüm buldum.

Fikir, bir "kafa" kutusundan başlayarak birbirini içeren, nesnelerin bir Ağacıdır (Grafik). Girdi dosyasını doğrusal olarak ayrıştırırken "current" kutusuna dizeler ve kutular eklersiniz ve kabın azami uzunluğu eklenirken ayarlanır. Bir kapsayıcı, sizi önceki kapsayıcısına geri izleyebileceğiniz, önceden tanımlanmış öğelerin miktarına ulaştığında. Giriş dosyasının sonunda, zaten hesaplanmış "maxLength" olan bir "kafa" kabına sahipsiniz, bu nedenle sadece print () yöntemini çağırırsınız.

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

Yazması gerçekten zevkli bir çözüm. Soruyu çok beğendim. Daha önce de belirttiğim gibi, minimalist bir yaklaşım değil çözüm zarafeti için gittim, ne yazık ki Java "-" * 4 üretecek kadar "Python" baskısına sahip değil :-)

İşte ungolfed versiyonu:

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
Bilirsin, bu bir kod golfü . En azından küçük bir çözüm hedeflemeyi denemelisin . Elegance hepsi güzel ve iyi, ama aslında gerekli değil, burada aranıyor.
Joey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.