Vẽ ngăn xếp phát triển của hộp


18

Nhiệm vụ

Trong thử thách này, nhiệm vụ của bạn là vẽ một đại diện nghệ thuật ASCII cho một số ngăn xếp có chiều cao tăng dần. Bạn được cho là đầu vào số lượng ngăn xếp, là một số nguyên dương. Ngăn xếp đầu tiên chứa một hộp kích thước 2x2. Ngăn xếp thứ hai chứa 2 hộp kích thước 3x3. Nói chung, kngăn xếp thứ chứa kcác hộp có kích thước (k+1)x(k+1).

Các đường viền của mỗi hộp được vẽ bằng các ký tự -|+và bên trong của chúng bao gồm khoảng trắng. Các hộp liền kề chia sẻ đường viền của chúng và các góc phải luôn được vẽ +, ngay cả khi chúng là một phần của đường viền của hộp khác.

Ví dụ

Đầu ra cho 1:

++
++

Đầu ra cho 2:

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

Đầu ra cho 3:

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

Đầu ra cho 5:

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

Quy tắc và chấm điểm

Đầu vào có thể được nhận từ STDIN, dưới dạng đối số dòng lệnh hoặc làm đối số hàm. Đầu ra phải đi đến STDOUT hoặc tương đương gần nhất. Bất kỳ số lượng khoảng trắng hữu hạn nào cũng được cho phép, như các dòng mới trước và sau, nhưng không thể có thêm khoảng trắng trước.

Đây là môn đánh gôn, vì vậy số byte thấp nhất sẽ thắng. Sơ hở tiêu chuẩn là không được phép.


2
Tôi nghĩ rằng đầu ra ascii này là một minh họa tốt cho cách thức nn-1tương đối chính. Hai điểm cộng sẽ không bao giờ trùng nhau.
mbomb007

1
Có giới hạn tối đa nào cho số đầu vào không?
Thomas Weller

@ThomasWeller Chỉ giới hạn tối đa của loại số nguyên gốc của ngôn ngữ của bạn.
Zgarb

Có vẻ như đây là một yếu tố hạn chế. Một số bài nộp sẽ không hoạt động Integer.MaxValuenhư đầu vào.
Thomas Weller

1
@ThomasWeller Ồ, tất nhiên, bạn đúng ... đó không phải là ý định của tôi để vô hiệu hóa các câu trả lời hiện có. Chúng ta hãy ghi đè rằng: một giải pháp sẽ hoạt động cho tất cả các đầu vào mà tổng số ký tự được yêu cầu trong đầu ra không vượt quá Integer.MaxValuehoặc tương đương.
Zgarb

Câu trả lời:



8

Java ( 407 349 ký tự)

Một vài ký tự nhờ @Zgarb và @Geobits

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

Không chắc điều này có tối ưu hay không, nhưng đây là lần thử đầu tiên của tôi, có lẽ tôi sẽ cố gắng đưa nó vào một ngôn ngữ chơi golf tốt hơn sau này. Mọi góp ý đều được chào đón!

Mở rộng

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

Kiểm tra nó ở đây.


5
Mẹo nhanh cho 10 byte: 1) Thay thế &&||bằng &|. 2) Di chuyển các intkhai báo vào for( for(int i=0,j,x,z;...). 3) Bạn có quá nhiều niềng răng ở cuối chức năng chơi gôn.
Geobits

4
Bạn có rất nhiều so sánh về hình thức a+1<=b+1; chúng có thể được thay thế bởi a<=b.
Zgarb

2
q*q+1có lẽ chỉ nên được gán cho một biến khác. Bạn sử dụng nó 9 lần hoặc lâu hơn và bạn có thể tiết kiệm một bó bằng cách nói a=q*q+1một lần. Ngoài ra, q*(q+1)chỉ là q*q+q.
Geobits

Tôi chỉ đang làm Geobits và Zgarb, cảm ơn vì những gợi ý!
Changming

Bạn có thể tìm kiếm một giải pháp đệ quy, có thể? Có vẻ như nên có một cái tốt đẹp.
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

Bit twiddling. Bit vặn vẹo khắp nơi.


3

Python, 188 byte

Về mặt toán học tính toán nhân vật ở mỗi x,yvị trí. Thật khó khăn khi thực hiện +in s ở cả hai mặt của mỗi hộp cũng như dừng các ô ngoài cùng bên phải +của n+1hộp thứ.

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

(8 * x + 1) **. 5 + 1 làm gì?
Abr001am

@ Agawa001 Trông giống như một hàm tam giác nghịch đảo.
Geobits

@Geobits Đánh bại tôi để trả lời mã của riêng tôi làm gì!
KSab

@Geobits yea tôi đã nghĩ về một cái gì đó như sàn $ sqrt (2 * n-sqrt (2 * n)) $,
Abr001am

1
Python @ThomasWeller sẽ tự động chuyển đổi đó để một longtrong đó có không giới hạn trên.
KSab

1

C # - 304 byte (chức năng)

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

hoặc 363 byte (mã đầy đủ)

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

Tôi đã cố gắng tránh nếu tuyên bố. Ung dung:

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

Giải pháp của tôi không hoạt động đối với bất kỳ đầu vào nào trong phạm vi Số nguyên như được xác định bởi OP. Tôi cần sử dụng longthay thế.
Thomas Weller

1

Ruby (205 byte)

Lấy số làm đối số dòng lệnh. Nó bắt đầu với một dòng mới không thành công, nhưng điều đó được cho phép.

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

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}

Tôi đã chạy nó trong Firefox. Bỏ qua "giao diện điều khiển thêm giữa các chuỗi. Đây chủ yếu là công cụ ES5 nhưng tôi sẽ cố gắng chơi golf này nhiều hơn nữa.

Ungolfed / 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>


1

Con trăn 2, 294 290

Tôi đã làm cho nó hoạt động, nhưng tôi vẫn cần phải chơi nó nhiều hơn. Mặc dù vậy, tôi rất hạnh phúc, điều đó thật khó khăn (ít nhất là đối với tôi)!

Có lẽ tôi sẽ thêm một lời giải thích sau, trừ khi nó rõ ràng ngay lập tức với ai đó ...? Tôi nghi ngờ điều đó.

Hãy thử nó ở đây

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)

0

Python - 243 byte

Tạo tất cả các cột, thay thế các lớp phủ trên các cột trừ cột đầu tiên. Sau đó, nó đệm với không gian, chuyển vị, và in.

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

Tôi đang xem xét dịch sang Pyth, nhưng tôi sẽ cần một sự thay thế cho chức năng pad.

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.