Zeichnen Sie wachsende Stapel von Boxen

18

Die Aufgabe

In dieser Herausforderung besteht Ihre Aufgabe darin, eine ASCII-Grafikdarstellung mehrerer Stapel von Kästen mit zunehmender Höhe zu zeichnen. Sie erhalten als Eingabe die Anzahl der Stapel, die eine positive ganze Zahl ist. Der erste Stapel enthält eine Schachtel Größe 2x2. Der zweite Stapel enthält 2 Kartons 3x3. Im Allgemeinen kenthält der dritte Stapel kSchachteln mit einer Größe (k+1)x(k+1).

Die Rahmen der einzelnen Kästchen werden anhand der Zeichen gezeichnet -|+, und ihr Inneres besteht aus Leerzeichen. Benachbarte Boxen teilen ihre Ränder und Ecken sollten immer mit gezeichnet werden +, auch wenn sie Teil eines Rahmens einer anderen Box sind.

Beispiele

Ausgabe für 1:

++
++

Ausgabe für 2:

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

Ausgabe für 3:

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

Ausgabe für 5:

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

Regeln und Wertung

Die Eingabe kann von STDIN als Befehlszeilenargument oder als Funktionsargument empfangen werden. Die Ausgabe muss auf STDOUT oder das nächstgelegene Äquivalent erfolgen. Es ist eine endliche Anzahl von nachgestellten Leerzeichen zulässig, ebenso wie vorangestellte und nachfolgende Zeilenumbrüche. Es dürfen jedoch keine zusätzlichen vorangestellten Leerzeichen vorhanden sein.

Das ist Code-Golf, also gewinnt die niedrigste Bytezahl. Standardlücken sind nicht zulässig.

Zgarb
quelle
2
Ich denke, diese ASCII-Ausgabe ist ein gutes Beispiel dafür, wie nund n-1sind relativ erstklassig. Zwei Pluspunkte überschneiden sich nie.
mbomb007
1
Gibt es eine Höchstgrenze für die eingegebene Anzahl?
Thomas Weller
@ThomasWeller Nur die maximale Grenze des nativen Ganzzahltyps Ihrer Sprache.
Zgarb
Dies scheint ein recht begrenzender Faktor zu sein. Einige der Einsendungen können nicht Integer.MaxValueals Eingabe verwendet werden.
Thomas Weller
1
@ThomasWeller Oh, du hast natürlich Recht ... es war nicht meine Absicht, bestehende Antworten zu entkräften. Lassen Sie uns Folgendes außer Kraft setzen: Eine Lösung sollte für alle Eingaben funktionieren, für die die Gesamtzahl der erforderlichen Zeichen in der Ausgabe nicht größer Integer.MaxValueoder gleich ist.
Zgarb

Antworten:

8

Java ( 407 349 Zeichen)

Ein paar Zeichen dank @Zgarb und @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();}}

Ich bin mir nicht sicher, ob dies optimal ist, aber es ist mein erster Versuch. Ich werde wahrscheinlich versuchen, es später in eine bessere Golfsprache zu bringen. Anregungen sind willkommen!

Erweitert

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

Schau es dir hier an.

Changming
quelle
5
Schnelle Tipps für 10 Bytes: 1) Ersetzen Sie &&und ||durch &und |. 2) intDeklarationen in das for( for(int i=0,j,x,z;...) verschieben. 3) Sie haben eine zu viele Zahnspangen am Ende Ihrer Golffunktion.
Geobits
4
Sie haben viele Vergleiche der Form a+1<=b+1; Sie können durch ersetzt werden a<=b.
Zgarb,
2
q*q+1sollte wahrscheinlich nur einer anderen Variablen zugewiesen werden. Sie verwenden es 9 Mal oder so, und Sie könnten einen Haufen sparen, indem Sie a=q*q+1einmal sagen . Ist auch q*(q+1)gerade q*q+q.
Geobits
Ich habe gerade Geobits und Zgarb gemacht, danke für die Vorschläge!
Changming
Sie könnten vielleicht nach einer rekursiven Lösung suchen? Es sieht so aus, als ob es einen schönen geben sollte.
mbomb007
5

Python 2, 144 128 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

Ein bisschen herumzudrehen. Überall ein bisschen herumwirbeln.

Sp3000
quelle
3

Python, 188 Bytes

Berechnet mathematisch das Zeichen an jeder x,yPosition. Es war schwierig, das +s auf beiden Seiten jeder Schachtel zu drucken und das rechte +s der n+1Schachteln zu stoppen .

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
quelle
Was macht (8 * x + 1) **. 5 + 1?
24.
@ Agawa001 Sieht aus wie eine umgekehrte Dreiecksfunktion.
Geobits
@Geobits Schlagen Sie mich, um zu beantworten, was mein eigener Code tut!
KSab
@ Geobits ja, ich dachte an etwas wie Boden $ sqrt (2 * n-sqrt (2 * n)) $,
Abr001am
1
@ThomasWeller Python wird , dass ein automatisch konvertieren , longdas hat keine Obergrenze.
KSab,
1

C # - 304 Bytes (Funktion)

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

oder 363 Bytes (vollständiger Code)

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

Ich habe versucht, if-Aussagen zu vermeiden. Ungolfed:

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
quelle
Meine Lösung funktioniert nicht für Eingaben im Integer-Bereich, wie von OP definiert. Ich müsste longstattdessen verwenden.
Thomas Weller
1

Ruby (205 Byte)

Nimmt die Nummer als Befehlszeilenargument. Es beginnt mit fehlgeschlagenen Zeilenumbrüchen, aber das ist erlaubt.

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

Ich habe dies in Firefox ausgeführt. Ignorieren Sie das, was "die Konsole zwischen den Strings hinzufügt. Das sind hauptsächlich ES5-Sachen, aber ich werde versuchen, dies mehr zu tun.

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

Python 2, 294, 290

Ich habe es zum Laufen gebracht, aber ich muss noch mehr Golf spielen. Ich bin so glücklich, das war hart (zumindest für mich)!

Ich werde wahrscheinlich später eine Erklärung hinzufügen, es sei denn, es ist jemandem sofort klar ...? Ich bezweifle es irgendwie.

Probieren Sie es hier aus

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

Python - 243 Bytes

Erzeugt alle Spalten, wobei die Überlappungen der Spalten mit Ausnahme der ersten ersetzt werden. Dann wird mit Leerzeichen aufgefüllt, transponiert und gedruckt.

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

Ich überlege, nach Pyth zu übersetzen, benötige aber einen Ersatz für die Pad-Funktion.

Maltysen
quelle