Gambarkan Tumbuh Tumpukan Kotak

18

Tugas

Dalam tantangan ini, tugas Anda adalah menggambar representasi seni ASCII dari beberapa tumpukan kotak dengan tinggi yang meningkat. Anda diberikan sebagai masukan jumlah tumpukan, yang merupakan bilangan bulat positif. Tumpukan pertama berisi satu kotak ukuran 2x2. Tumpukan kedua berisi 2 kotak ukuran 3x3. Secara umum, ktumpukan th berisi kkotak ukuran (k+1)x(k+1).

Batas setiap kotak digambar menggunakan karakter -|+, dan interiornya terdiri dari spasi putih. Kotak-kotak yang berdekatan berbagi batas, dan sudut harus selalu ditarik +, bahkan ketika mereka merupakan bagian dari batas kotak lain.

Contohnya

Output untuk 1:

++
++

Output untuk 2:

 +-+
 | |
 +-+
++ |
++-+

Output untuk 3:

   +--+
   |  |
   |  |
   +--+
   |  |
 +-+  |
 | +--+
 +-+  |
++ |  |
++-+--+

Output untuk 5:

          +----+
          |    |
          |    |
          |    |
          |    |
          +----+
          |    |
          |    |
          |    |
      +---+    |
      |   +----+
      |   |    |
      |   |    |
      +---+    |
      |   |    |
      |   +----+
   +--+   |    |
   |  +---+    |
   |  |   |    |
   +--+   |    |
   |  |   +----+
 +-+  +---+    |
 | +--+   |    |
 +-+  |   |    |
++ |  |   |    |
++-+--+---+----+

Aturan dan Penilaian

Input dapat diterima dari STDIN, sebagai argumen baris perintah, atau sebagai argumen fungsi. Output harus pergi ke STDOUT atau setara terdekat. Setiap jumlah ruang trailing terbatas yang diperbolehkan, seperti yang mendahului dan mengikuti baris baru, tetapi tidak ada ruang tambahan sebelumnya.

Ini adalah kode-golf, sehingga jumlah byte terendah menang. Celah standar tidak diijinkan.

Zgarb
sumber
2
Saya pikir output ascii ini adalah ilustrasi yang baik untuk bagaimana ndan n-1relatif prima. Dua plus tidak akan pernah tumpang tindih.
mbomb007
1
Apakah ada batas maksimum untuk nomor input?
Thomas Weller
@ThomasWeller Hanya batas maksimum jenis bilangan bulat asli bahasa Anda.
Zgarb
Tampaknya ini adalah faktor pembatas. Beberapa kiriman tidak akan berfungsi Integer.MaxValuesebagai masukan.
Thomas Weller
1
@ ThomasWeller Oh, tentu saja Anda benar ... itu bukan maksud saya untuk membatalkan jawaban yang ada. Mari kita tentukan bahwa: solusi harus bekerja untuk semua input yang jumlah karakter yang diperlukan dalam output tidak melebihi Integer.MaxValueatau setara.
Zgarb

Jawaban:

9

CJam, 64 60 58 byte

]ri:X{'|'}{I))*\I**XX*)Se[s}:L~:M.e>S'-LaI*~M}fI]zN*'}/'+*

Membangun setiap kolom sekaligus.

Cobalah online di sini

Pengoptimal
sumber
8

Jawa ( 407 349 karakter)

Beberapa karakter berkat @Zgarb dan @Geobits

Kode

void s(int q){int d,h,y,i,j,x,z,t=q*q+1;char b;for(i=0;i<t;i++){z=x=0;d=t-i;for(j=0;j<(q*q+q)/2+1;j++){b=' ';h=x*x+1;if(x==z){y=x+1;if((d<=h&d%(x==0?1:x)==(x==1?0:1))|(y<=q&d<=y*y+1&d%(y==0?1:y)==(y==1?0:1)))b='+';else if(d<=h|y<=q&d<=y*y+1)b='|';x++;z=1;}else{if(d<=h&d%(x==0?1:x)==(x==1?0:1))b='-';z++;}System.out.print(b);}System.out.println();}}

Tidak yakin apakah ini optimal, tetapi ini adalah upaya pertama saya, saya mungkin akan mencoba memasukkannya ke dalam bahasa golf yang lebih baik nanti. Ada saran dipersilahkan!

Diperluas

class StackingBlocks{
    public static void main(String[]a){
        int d,h,y,i,j,x,z,t,q=10;
        t=q*q+1;
        char b;
        for(i=0;i<t;i++){
            z=x=0;
            d=t-i;
            for(j=0;j<(q*q+q)/2+1;j++){
                b=' ';
                h=x*x+1;
                if(x==z){
                    y=x+1;
                    if((d<=h&d%(x==0?1:x)==(x==1?0:1))|(y<=q&d<=y*y+1&d%(y==0?1:y)==(y==1?0:1)))
                        b='+';
                    else if(d<=h|y<=q&d<=y*y+1)
                        b='|';
                    x++;
                    z=1;
                }else{
                    if(d<=h&d%(x==0?1:x)==(x==1?0:1))
                        b='-';
                    z++;
                }
                System.out.print(b);
            }
            System.out.println();
        }
    }
}

Lihat disini.

Berubah
sumber
5
Kiat cepat untuk 10 byte: 1) Ganti &&dan ||dengan &dan |. 2) Pindahkan intdeklarasi ke for( for(int i=0,j,x,z;...). 3) Anda memiliki satu kawat gigi terlalu banyak pada akhir fungsi golf Anda.
Geobits,
4
Anda memiliki banyak perbandingan bentuk a+1<=b+1; mereka dapat digantikan oleh a<=b.
Zgarb
2
q*q+1mungkin hanya boleh ditugaskan ke variabel lain. Anda menggunakannya 9 kali atau lebih, dan Anda bisa menghemat banyak dengan mengatakan a=q*q+1sekali. Juga, q*(q+1)adil q*q+q.
Geobits,
Saya baru saja melakukan itu Geobits dan Zgarb, terima kasih atas sarannya!
Mengubah
Anda bisa mencari solusi rekursif, mungkin? Sepertinya harus ada yang bagus.
mbomb007
5

Python 2, 144 128 byte

n=input()
i=n*n
while-~i:j=x=1;l="";exec'y=i%j<1;z=i>j*j;l+=j*z*" "or"|+"[x|y]+" -"[y]*~-j;x=y^z>z;j+=1;'*n;print l+"|+"[x];i-=1

Sedikit memutar-mutar. Sedikit memutar-mutar di mana-mana.

Sp3000
sumber
3

Python, 188 byte

Secara matematis menghitung karakter di setiap x,yposisi. Itu sulit membuat+ cetakan di kedua sisi setiap kotak serta menghentikan bagian paling kanan +dari apa yang akan menjadi n+1kotak.

n=input();l=1;c=0
for y in range(n*n,-1,-1):
 s=""
 for x in range((n*n+n)/2+1):k=((8*x+1)**.5+1)/2;i=int(k);b=y<=i**2;s+=" |-+"[((k==i)+2*((y%l+c)*(y%i+(k==n+1))<1))*b];l=i;c=b^1
 print s
KSab
sumber
apa yang dilakukan (8 * x + 1) **. 5 + 1 lakukan?
Abr001am
@ Agawa001 Sepertinya fungsi segitiga terbalik.
Geobits,
@ Geobits Kalahkan saya untuk menjawab apa yang dilakukan kode saya sendiri!
KSab
@ Geobits ya saya sedang memikirkan sesuatu seperti lantai $ sqrt (2 * n-sqrt (2 * n)) $,
Abr001am
1
@ThomasWeller python akan secara otomatis mengonversinya menjadi longyang tidak memiliki batas atas.
KSab
1

C # - 304 byte (fungsi)

void b(int s){int h=s*s,w=h+s>>1,x,y,j;var c=new int[w+1,h+1];for(;s>0;s--){for(y=s*s-s;y>=0;y-=s){x=s*s-s>>1;for(j=0;j<s;){c[x+j,y]=c[x+j,y+s]=13;c[x,y+j]=c[x+s,y+j++]=92;}c[x,y]=c[x+s,y]=c[x+s,y+s]=c[x,y+s]=11;}}for(y=h;y>=0;y--){for(x=0;x<=w;x++)Console.Write((char)(32+c[x,y]));Console.WriteLine();}}

atau 363 byte (kode lengkap)

namespace System{class C{static void Main(string[]a){int s=int.Parse(a[0]),h=s*s,w=h+s>>1,x,y,j;var c=new int[w+1,h+1];for(;s>0;s--){for(y=s*s-s;y>=0;y-=s){x=s*s-s>>1;for(j=0;j<s;){c[x+j,y]=c[x+j,y+s]=13;c[x,y+j]=c[x+s,y+j++]=92;}c[x,y]=c[x+s,y]=c[x+s,y+s]=c[x,y+s]=11;}}for(y=h;y>=0;y--){for(x=0;x<=w;x++)Console.Write((char)(32+c[x,y]));Console.WriteLine();}}}}

Saya mencoba menghindari pernyataan if. Tidak Disatukan:

namespace N
{
    public class Explained
    {
        static void boxes(string[] args)
        {
            int size = int.Parse(args[0]);
            int height = size * size + 1;
            int width = size * (size + 1) / 2 + 1;
            var canvas = new int[width, height];
            for (; size > 0; size--)
                drawboxes(size, canvas);

            for (int y = height - 1; y >= 0; y--)
            {
                for (int x = 0; x < width; x++)
                    Console.Write((char)(32 + canvas[x, y]));
                Console.WriteLine();
            }
        }

        static void drawboxes(int size, int[,] canvas)
        {
            int x = size * (size - 1) / 2;
            for (int i = size - 1; i >= 0; i--)
            {
                drawbox(x, i * size, size, canvas);
            }
        }

        static void drawbox(int x, int y, int size, int[,] canvas)
        {
            for (int i = 0; i < size; i++)
            {
                canvas[x + i, y] = 13; // +32 = '-'
                canvas[x + i, y + size] = 13;
                canvas[x, y + i] = 92; // +32 = '|'
                canvas[x + size, y + i] = 92;
            }
            canvas[x, y] = 11; // +32 = '+'
            canvas[x + size, y] = 11;
            canvas[x + size, y + size] = 11;
            canvas[x, y + size] = 11;
        }
    }
}
Thomas Weller
sumber
Solusi saya tidak berfungsi untuk input rentang Integer seperti yang didefinisikan oleh OP. Saya harus menggunakan longsebagai gantinya.
Thomas Weller
1

Ruby (205 byte)

Mengambil nomor sebagai argumen baris perintah. Itu dimulai dengan baris baru yang gagal, tetapi itu dibolehkan.

n=$*[0].to_i
m=n+1
f=m.times.inject(:+)+1
c=((" "*f+p=?+)*n*m).split p
y=0
1.upto(n){|b|(b*b+1).times{|x|d=x%b==0;r=c[x]
d&&b.times{|g|r[y+g]=?-}
r[y]=d||r[y]==p ?p:?|
r[y+b]=d ?p:?|}
y+=b}
puts c.reverse
Arne Brasseur
sumber
1

JavaScript (ES6), 293 byte

(n,o='',r,f,t,u,b,c,e=n*n+1,i)=>{for(t=0;e>t;t++){for(c=b=0,d=e-t,u=0;(n*n+n)/2+1>u;u++)i=" ",r=b*b+1,b==c?(f=b+1,d<=r&d%(0==b?1:b)==(1==b?0:1)|n>=f&d<=f*f+1&d%(0==f?1:f)==(1==f?0:1)?i="+":d<=r|n>=f&d<=f*f+1&&(i="|"),b++,c=1):(d<=r&d%(0==b?1:b)==(1==b?0:1)&&(i="-"),c++),o+=i;o+="\n"}return o}

Saya menjalankan ini di Firefox. Abaikan" penambahan konsol di antara string. Ini sebagian besar barang ES5 tapi saya akan mencoba bermain golf ini lebih banyak.

Tidak dinegosiasikan / ES5

function box(n, o, r, f, t, u, b, c, e, i) {
  if (o === undefined) o = "";
  if (e === undefined) e = n * n + 1;
  return (function() {
    for (t = 0; e > t; t++) {
      for (c = b = 0, d = e - t, u = 0;
        (n * n + n) / 2 + 1 > u; u++) i = " ", r = b * b + 1, b == c ? (f = b + 1, d <= r & d % (0 == b ? 1 : b) == (1 == b ? 0 : 1) | n >= f & d <= f * f + 1 & d % (0 == f ? 1 : f) == (1 == f ? 0 : 1) ? i = "+" : d <= r | n >= f & d <= f * f + 1 && (i = "|"), b++, c = 1) : (d <= r & d % (0 == b ? 1 : b) == (1 == b ? 0 : 1) && (i = "-"), c++), o += i;
      o += "\n";
    }
    return o;
  })();
}

document.getElementById('g').onclick = function(){ document.getElementById('o').innerHTML = box(+document.getElementById('v').value) };
<input id="v"><button id="g">Run</button><pre id="o"></pre>

Downgoat
sumber
1

Python 2, 294 290

Saya membuatnya bekerja, tetapi saya masih perlu golf lebih banyak. Saya sangat senang, itu sulit (bagi saya, setidaknya)!

Saya mungkin akan menambahkan penjelasan nanti, kecuali segera jelas bagi seseorang ...? Aku agak meragukannya.

Coba di sini

n=input()
w=n*n+n+2>>1
a=eval(`[[' ']*w]*-~n**2`)
r=range
j=[i*i+i>>1for i in r(n+1)]
p=0
for i in r(w):
 if i in j:
    p+=p<n
    for k in r(p*p+1):a[~k][i]='+'if k%p<1or' '<a[~k][i-1]<'.'else'|'
 else:
    for k in r(p*p+1):a[~k][i]=' 'if k%p else'-'
print'\n'.join(''.join(i)for i in a)
mbomb007
sumber
0

Python - 243 byte

Menghasilkan semua kolom, menggantikan tumpang tindih pada kolom kecuali yang pertama. Lalu, bantalan dengan spasi, transpos, dan cetakan.

Q=input()
Y=[]
for i in range(Q):
    f="+"+i*"-"+"+";x=map(list,zip(*([f]+["|"+" "*i+"|"]*i)*(i+1)+[f]))
    if i:y=Y.pop();x[0][-len(y):]=y
    Y+=x
print"\n".join("".join(i)for i in zip(*["".join(j[::-1]).ljust(Q*Q+1," ")for j in Y])[::-1])

Saya sedang mempertimbangkan untuk menerjemahkan ke Pyth, tetapi saya akan membutuhkan pengganti untuk fungsi pad.

Maltysen
sumber