Dibuja pilas de cajas en crecimiento

18

La tarea

En este desafío, su tarea es dibujar una representación de arte ASCII de varias pilas de cajas de altura creciente. Se le da como entrada el número de pilas, que es un número entero positivo. La primera pila contiene una caja de tamaño 2x2. La segunda pila contiene 2 cajas de tamaño 3x3. En general, la kpila th contiene kcajas de tamaño (k+1)x(k+1).

Los bordes de cada cuadro se dibujan con los caracteres -|+, y su interior consiste en espacios en blanco. Las cajas adyacentes comparten sus bordes, y las esquinas siempre deben dibujarse +, incluso cuando forman parte de un borde de otra caja.

Ejemplos

Salida para 1:

++
++

Salida para 2:

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

Salida para 3:

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

Salida para 5:

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

Reglas y puntuación

La entrada se puede recibir de STDIN, como argumento de línea de comando o como argumento de función. La salida debe ir a STDOUT o equivalente más cercano. Se permite cualquier cantidad finita de espacios en blanco finales, al igual que las líneas nuevas anteriores y posteriores, pero no puede haber espacios anteriores adicionales.

Este es el código de golf, por lo que gana el conteo de bytes más bajo. Las lagunas estándar no están permitidas.

Zgarb
fuente
2
Creo que este resultado ASCII es una buena ilustración de cómo ny n-1son relativamente primos. Dos ventajas nunca se superpondrán.
mbomb007
1
¿Hay algún límite máximo para el número de entrada?
Thomas Weller
@ThomasWeller Solo el límite máximo del tipo de entero nativo de su idioma.
Zgarb
Parece que este es un factor bastante limitante. Algunas de las presentaciones no funcionarán Integer.MaxValuecomo entrada.
Thomas Weller
1
@ThomasWeller Oh, tienes razón, por supuesto ... no era mi intención invalidar las respuestas existentes. Anulemos eso: una solución debería funcionar para todas las entradas para las cuales el número total de caracteres requeridos en la salida no excede Integer.MaxValueo es equivalente.
Zgarb

Respuestas:

9

CJam, 64 60 58 bytes

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

Construyendo cada columna a la vez.

Pruébalo en línea aquí

Optimizador
fuente
8

Java ( 407 349 caracteres)

Algunos caracteres gracias a @Zgarb y @Geobits

Código

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

No estoy seguro si esto es óptimo, pero es mi primer intento, probablemente intentaré ponerlo en un mejor lenguaje de golf más adelante. Cualquier sugerencia es bienvenida!

Expandido

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

Compruébalo aquí.

Changming
fuente
55
Consejos rápidos para 10 bytes: 1) Reemplazar &&y ||con &y |. 2) Mover intdeclaraciones a for( for(int i=0,j,x,z;...). 3) Tienes demasiadas llaves al final de tu función de golf.
Geobits
44
Tienes muchas comparaciones de la forma a+1<=b+1; que pueden ser reemplazados por a<=b.
Zgarb
2
q*q+1probablemente solo debería asignarse a otra variable. Lo usas 9 veces más o menos, y puedes ahorrar un montón diciendo a=q*q+1una vez. Además, q*(q+1)es justo q*q+q.
Geobits
Estaba haciendo eso Geobits y Zgarb, ¡gracias por las sugerencias!
Changming
¿Podría buscar una solución recursiva, tal vez? Parece que debería haber una buena.
mbomb007
5

Python 2, 144128 bytes

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

Un poco tonto. Un poco girando por todas partes.

Sp3000
fuente
3

Python, 188 bytes

Calcula matemáticamente el personaje en cada x,yposición. Fue complicado hacer que la +letra s se imprima en ambos lados de cada cuadro, así como detener el extremo derecho +de lo que serían las n+1cajas.

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
fuente
¿Qué hace (8 * x + 1) **. 5 + 1?
Abr001am
@ Agawa001 Parece una función de triángulo inverso.
Geobits
@Geobits ¡Vence a responder lo que hace mi propio código!
KSab
@Geobits sí, estaba pensando en algo así como suelo $ sqrt (2 * n-sqrt (2 * n)) $,
Abr001am
1
@ThomasWeller python lo convertirá automáticamente en uno longque no tenga límite superior.
KSab
1

C # - 304 bytes (función)

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

o 363 bytes (código completo)

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

Traté de evitar si las declaraciones. Sin golf:

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
fuente
Mi solución no funciona para ninguna entrada de rango entero según lo definido por OP. Necesitaría usar longen su lugar.
Thomas Weller
1

Rubí (205 bytes)

Toma el número como argumentos de línea de comando. Comienza con un fallo que lleva a las nuevas líneas, pero eso está permitido.

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
fuente
1

JavaScript (ES6), 293 bytes

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

Ejecuté esto en Firefox. Ignora la "consola que agrega entre las cadenas. Esto es principalmente de ES5, pero intentaré jugar más al golf.

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>

Downgoat
fuente
1

Pitón 2, 294 290

Lo hice funcionar, pero todavía necesito jugar más al golf. Sin embargo, estoy muy feliz, ¡eso fue duro (al menos para mí)!

Probablemente agregaré una explicación más tarde, a menos que sea inmediatamente claro para alguien ...? Lo dudo un poco.

Pruébalo aquí

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
fuente
0

Python - 243 bytes

Genera todas las columnas, reemplazando las superposiciones en las columnas, excepto la primera. Luego se rellena con espacios, transposiciones e impresiones.

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

Estoy considerando traducir a Pyth, pero necesitaré un reemplazo para la función pad.

Maltysen
fuente