성장하는 상자 더미 그리기


18

작업

이 도전에서, 당신의 임무는 높이가 증가하는 여러 상자 더미의 ASCII 예술 표현을 그리는 것입니다. 스택 수를 입력으로 제공하며 양의 정수입니다. 첫 번째 스택은 하나의 크기의 상자를 포함합니다 2x2. 두 번째 스택에는 2 개의 상자 크기가 3x3있습니다. 일반적으로 kth 스택에는 ksize의 상자가 포함 됩니다 (k+1)x(k+1).

각 상자의 테두리는 문자를 사용하여 그려지며 -|+내부는 공백으로 구성됩니다. 인접한 상자는 테두리를 공유하며 +다른 상자의 테두리에 속하더라도 모서리는 항상로 그려야 합니다.

에 대한 출력 1:

++
++

에 대한 출력 2:

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

에 대한 출력 3:

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

에 대한 출력 5:

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

규칙과 채점

입력은 STDIN, 명령 행 인수 또는 함수 인수로 수신 될 수 있습니다. 출력 STDOUT 또는 가장 가까운 값으로 이동 해야합니다 . 선행 및 후행 개행과 같이 유한 한 양의 후행 공백이 허용되지만 추가 선행 공백은있을 수 없습니다.

이것은 코드 골프이므로 가장 낮은 바이트 수가 이깁니다. 표준 허점은 허용되지 않습니다.


2
나는이 ASCII 출력이 어떻게 n그리고 n-1상대적으로 프라임에 대한 좋은 예라고 생각합니다 . 두 개의 플러스가 겹치지 않습니다.
mbomb007

1
입력 번호에 대한 최대 제한이 있습니까?
토마스 웰러

@ThomasWeller 언어의 기본 정수 유형의 최대 한계.
Zgarb

이것은 상당히 제한적인 요소 인 것 같습니다. 제출물 중 일부는 Integer.MaxValue입력으로 작동하지 않습니다 .
토마스 웰러

1
@ThomasWeller 아, 물론 당신은 옳습니다 ... 기존 답변을 무효화하려는 의도는 아닙니다. 출력에 필요한 총 문자 수를 초과하지 않는 모든 입력에 대해 솔루션이 작동해야합니다 Integer.MaxValue.
Zgarb

답변:



8

자바 ( 407 개 349 문자)

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

이것이 최선인지는 확실하지 않지만, 이것이 나의 첫 번째 시도 일 것입니다. 나중에 더 나은 골프 언어로 만들려고합니다. 어떤 제안이라도 환영합니다!

넓히는

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

여기서 확인하십시오.


5
1) 교체 : 10 바이트에 대한 빠른 팁 &&||&|. 2) int선언을 for( for(int i=0,j,x,z;...) 로 옮깁니다 . 3) 골프 경기 종료시 버팀대가 너무 많습니다.
Geobits

4
당신은 형태에 대한 많은 비교가 있습니다 a+1<=b+1; 로 대체 될 수 있습니다 a<=b.
Zgarb

2
q*q+1아마도 다른 변수에 할당되어야합니다. 9 번 정도 사용하면 a=q*q+1한 번만 말하면 무리를 구할 수 있습니다. 또한 q*(q+1)입니다 q*q+q.
Geobits

나는 단지 Geobits와 Zgarb를하고있었습니다. 제안에 감사드립니다!
Changming 2016 년

재귀 솔루션을 찾을 수 있습니까? 좋은 것이 있어야합니다.
mbomb007

5

파이썬 2, 144128 바이트

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

비트 꼬기. 사방에 조금 꼬부라.


3

파이썬, 188 바이트

x,y위치 에서 문자를 수학적으로 계산합니다 . +각 상자의 양면에 인쇄 하는 것은 까다 로웠으며 상자 +가 무엇인지 가장 오른쪽에 표시하지 않았습니다 n+1.

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은 무엇을합니까?
Abr001am


@Geobits 내 자신의 코드가 무엇을하는지 대답 해주세요!
KSab

@Geobits 그래, 나는 floor $ sqrt (2 * n-sqrt (2 * n)) $ 같은 것을 생각하고 있었다
Abr001am

1
@ThomasWeller python은 자동으로 상한 long없는 것으로 변환합니다 .
KSab

1

C #-304 바이트 (기능)

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

또는 363 바이트 (전체 코드)

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

if 문을 피하려고했습니다. 언 골프 드 :

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

내 솔루션은 OP로 정의 된 정수 범위의 입력에 대해 작동하지 않습니다. long대신 사용해야 합니다.
토마스 웰러

1

루비 (205 바이트)

숫자를 명령 행 인수로 사용합니다. 실패한 줄 바꿈으로 시작하지만 허용됩니다.

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

자바 스크립트 (ES6), 293 바이트

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

Firefox에서 이것을 실행했습니다. 무시"콘솔이 문자열 사이에 추가 것을 . 이것은 주로 ES5 물건이지만 이것을 더 골프하려고합니다.

언 골프 / 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

파이썬 2, 294 (290)

나는 그것을 작동 시키지만 여전히 골프를 더해야합니다. 그러나 나는 너무나 행복했다.

누군가에게 즉시 명확하지 않으면 나중에 설명을 추가 할 것입니다 ...? 나는 그것을 의심한다.

여기 사용해보십시오

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

파이썬-243 바이트

모든 열을 생성하고 첫 번째 열을 제외한 열의 겹침을 대체합니다. 그런 다음 공백으로 채우고 조바꿈하고 인쇄합니다.

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

Pyth 로의 변환을 고려하고 있지만 패드 기능을 대체해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.