Dessinez des piles croissantes de boîtes

18

La tâche

Dans ce défi, votre tâche consiste à dessiner une représentation artistique ASCII de plusieurs piles de boîtes de hauteur croissante. On vous donne en entrée le nombre de piles, qui est un entier positif. La première pile contient une boîte de taille 2x2. La deuxième pile contient 2 boîtes de taille 3x3. En général, la ke pile contient des kboîtes de taille (k+1)x(k+1).

Les bordures de chaque boîte sont dessinées à l'aide des caractères -|+et leur intérieur est constitué d'espaces. Les boîtes adjacentes partagent leurs bordures et les coins doivent toujours être dessinés avec +, même lorsqu'ils font partie d'une bordure d'une autre boîte.

Exemples

Sortie pour 1:

++
++

Sortie pour 2:

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

Sortie pour 3:

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

Sortie pour 5:

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

Règles et notation

L'entrée peut être reçue de STDIN, comme argument de ligne de commande ou comme argument de fonction. La sortie doit aller vers STDOUT ou son équivalent le plus proche. Toute quantité finie d'espaces blancs de fin est autorisée, tout comme les sauts de ligne précédents et finaux, mais il ne peut pas y avoir d'espaces précédents supplémentaires.

Il s'agit de code-golf, donc le nombre d'octets le plus bas l'emporte. Les failles standard ne sont pas autorisées.

Zgarb
la source
2
Je pense que cette sortie ascii est une bonne illustration de la façon dont net n-1sont relativement premiers. Deux avantages ne se chevaucheront jamais.
mbomb007
1
Y a-t-il une limite maximale pour le numéro d'entrée?
Thomas Weller
@ThomasWeller Seule la limite maximale du type d'entier natif de votre langue.
Zgarb
Il semble que ce soit un facteur assez limitatif. Certaines soumissions ne fonctionneront pas Integer.MaxValuecomme entrée.
Thomas Weller
1
@ThomasWeller Oh, vous avez bien sûr raison ... ce n'était pas mon intention d'invalider les réponses existantes. Supprimons cela: une solution devrait fonctionner pour toutes les entrées pour lesquelles le nombre total de caractères requis dans la sortie ne dépasse pas Integer.MaxValueou n'est pas équivalent.
Zgarb

Réponses:

9

CJam, 64 60 58 octets

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

Construire chaque colonne à la fois.

Essayez-le en ligne ici

Optimiseur
la source
8

Java ( 407 349 caractères)

Quelques caractères grâce à @Zgarb et @Geobits

Code

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

Je ne sais pas si c'est optimal, mais c'est ma première tentative, j'essaierai probablement de le mettre dans une meilleure langue de golf plus tard. Toutes les suggestions sont les bienvenues!

Étendu

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

Vérifiez le ici.

Changming
la source
5
Conseils rapides pour 10 octets: 1) Remplacez &&et ||par &et |. 2) Déplacez les intdéclarations dans le for( for(int i=0,j,x,z;...). 3) Vous avez un appareil de trop à la fin de votre fonction de golf.
Geobits
4
Vous avez beaucoup de comparaisons du formulaire a+1<=b+1; ils peuvent être remplacés par a<=b.
Zgarb
2
q*q+1devrait probablement juste être assigné à une autre variable. Vous l'utilisez environ 9 fois, et vous pourriez économiser un tas en disant a=q*q+1une fois. Aussi, q*(q+1)c'est juste q*q+q.
Geobits
Je faisais juste ça Geobits et Zgarb, merci pour les suggestions!
Changming
Vous pourriez chercher une solution récursive, peut-être? Il semble qu'il devrait y en avoir un joli.
mbomb007
5

Python 2, 144 128 octets

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 twiddling partout.

Sp3000
la source
3

Python, 188 octets

Calcule mathématiquement le caractère à chaque x,yposition. Il était difficile de faire l' +impression des deux côtés de chaque boîte ainsi que d'arrêter les +s les plus à droite de ce qui serait les n+1boîtes.

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
la source
que fait (8 * x + 1) **. 5 + 1?
Abr001am
@ Agawa001 Ressemble à une fonction triangle inverse.
Geobits
@Geobits Battez-moi pour répondre à ce que fait mon propre code!
KSab
@Geobits oui je pensais à quelque chose comme floor $ sqrt (2 * n-sqrt (2 * n)) $,
Abr001am
1
@ThomasWeller python convertira automatiquement cela en un longqui n'a pas de limite supérieure.
KSab
1

C # - 304 octets (fonction)

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

ou 363 octets (code complet)

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

J'ai essayé d'éviter les déclarations if. Non 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
la source
Ma solution ne fonctionne pour aucune entrée de plage entière telle que définie par OP. Je devrais utiliserlong place.
Thomas Weller
1

Rubis (205 octets)

Prend le nombre comme arguments de ligne de commande. Cela commence par un échec menant à des nouvelles lignes, mais c'est autorisé.

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
la source
1

JavaScript (ES6), 293 octets

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

J'ai couru cela dans Firefox. Ignorez la "console ajoute entre les chaînes. Ce sont principalement des trucs ES5 mais je vais essayer de jouer au golf plus.

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
la source
1

Python 2, 294 290

Je l'ai fait fonctionner, mais j'ai encore besoin de jouer au golf. Je suis si heureux, cependant, c'était difficile (pour moi, au moins)!

J'ajouterai probablement une explication plus tard, à moins que ce ne soit immédiatement clair pour quelqu'un ...? J'en doute un peu.

Essayez-le ici

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
la source
0

Python - 243 octets

Génère toutes les colonnes, en remplaçant les chevauchements sur les colonnes sauf la première. Ensuite, il remplit d'espaces, transpose et imprime.

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

J'envisage de traduire en Pyth, mais j'aurai besoin d'un remplacement pour la fonction pad.

Maltysen
la source