3D ASCII Block Gebäude

82

Herausforderung

Schreiben Sie ein Programm, das ein 11x11-Array von Ganzzahlen verwendet und ein 3D-ASCII-Blockgebäude erstellt, wobei jeder Wert im Array die Höhe einer Blockspalte an den Koordinaten darstellt, die mit der Arrayposition übereinstimmen. Eine negative Höhe ist eine "schwebende" Spalte - nur der obere Block ist sichtbar.

Beispiel

                                                        __________________
                                        ___            /\__\__\__\__\__\__\
 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /\__\          /\/\__\__\__\__\__\__\
 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /\/__/         /\/\/__/__/__/__/__/__/
 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /\/\__\        /\/\/\__\      /\/\/__/
 1, 0, 0, 7,-7,-7,-7,-7, 7, 0, 0,    \/\/\__\      /\/\/\/__/     /\/\/__/
 0, 0, 0, 7,-7,-7,-7,-7, 7, 0, 0,     \/\/__/     /\/\/\/\__\    /\/\/__/
 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,      \/\__\    /\/\/\/\/__/   /\/\/__/
 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,       \/__/    \/\/\/\/\__\_  \/\/__/
 1, 0, 0, 4, 3, 2, 1, 0, 0, 0, 1,                 \/\/\/\/__/_\_ \/__/
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,            ___   \/\/\/__/__/_\_         ___
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,           /\__\   \/\/__/__/__/_\       /\__\
 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,           \/\__\   \/__/__/__/__/       \/\__\
                                             \/\__\_________         ______\/\__\
                                              \/\__\__\__\__\       /\__\__\__\__\
                                               \/__/__/__/__/       \/__/__/__/__/

Eingang

Die Eingabe ist eine Liste von 121 Ganzzahlen, die entweder von stdin gelesen (die Wahl des Trennzeichens liegt bei Ihnen) oder als Array übergeben werden (kann 1D oder 2D sein).

Die Höhen liegen im Bereich von -11 bis 11.

Ausgabe

Das generierte Gebäude kann in stdout geschrieben, direkt auf dem Bildschirm angezeigt oder als durch Zeilenumbrüche getrennte Zeichenfolge zurückgegeben werden.

Führende und nachfolgende Leerzeichen sind zulässig.

Gebäuderegeln

Die Form eines einzelnen 3D-Blocks sieht folgendermaßen aus:

 ___
/\__\
\/__/

Und ein 2x2x2-Blockwürfel sieht so aus:

  ______
 /\__\__\
/\/\__\__\
\/\/__/__/
 \/__/__/

Wenn sich Blöcke überlappen, hat ein höherer Block Vorrang vor einem niedrigeren, vorne liegende Blöcke haben Vorrang vor den weiter hinten liegenden und links liegende Blöcke haben Vorrang vor den rechts liegenden Blöcken. Der einzige Sonderfall ist, dass die oberste Zeile eines Blocks niemals ein dahinterstehendes Nicht-Leerzeichen überschreiben darf.

Die Interpretation der Spaltenhöhen lässt sich am besten anhand einer 2D-Darstellung von der Seite erklären.

HEIGHT:  1    2    3   -3   -2   -1
                  __   __
             __  |__| |__|  __
        __  |__| |__|      |__|  __
       |__| |__| |__|           |__|

Testfälle

Wenn Sie Ihre Lösung an einigen weiteren Eingaben ausprobieren möchten, habe ich hier einige Testfälle zusammengestellt .

Gewinnen

Dies ist , also gewinnt die kürzeste Übermittlung (in Bytes).

James Holderness
quelle
9
Oh, Junge, mach dich bereit für mehr als 300-Byte-Lösungen. Gute Herausforderung. +1
totalhuman
7
@totallyhuman Nein, Dennis wird in 20 Minuten eine 9-Byte-Lösung dafür haben.
Diakon
3
Muss die Perspektive so sein, wie sie links unten in den Eingabedaten im Vordergrund angezeigt wird? Die Tatsache, dass dies nicht das erste oder letzte Datenelement ist, erschwert es. Ist es akzeptabel, entweder 1. die Zuordnung beizubehalten und die Ausgabe mit der rechten unteren Spalte im Vordergrund zu zeichnen oder 2. ein Spiegelbild oder eine 90-Grad-Drehung der Daten zu zeichnen? Beides würde dazu führen, dass das letzte Datenelement mit der Spalte im Vordergrund übereinstimmt, was einfacher wäre.
Level River St
3
Ich bin geneigt, eine echte Spiel-Engine (oder einen Teil davon) zu verwenden, um ein Foto zu rendern und es in ASCII zu konvertieren
Stan Strum
@LevelRiverSt Das scheint eine vernünftige Aufforderung zu sein - Sie können die Reihenfolge der 121 Eingabeelemente so wählen, wie es für Ihre Lösung am sinnvollsten ist, solange Ihre Reihenfolge konsistent ist. Es muss möglich sein, alle Arten von Layouts zu erstellen, die mit der Standardbestellung erstellt werden können.
James Holderness

Antworten:

25

Kohle , 70 69 68 Bytes

≔E¹¹⮌I⪪S,θF²F¹¹F¹¹F¹¹«J⁻⁻⁺λκ×μ³ι⁻λκ≔§§θλμη¿∨⁼±η⊕κ‹κη¿ι“↗⊟&⁹κUhnI”___

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

≔E¹¹⮌I⪪S,θ

Lesen Sie das Array, teilen Sie jede Zeile durch Kommas auf und setzen Sie es in eine Ganzzahl um, kehren Sie aber auch jede Zeile um, da Sie von rechts nach links zeichnen möchten, sodass die linken Spalten die rechten Spalten überschreiben. (Andere Dimensionen haben bereits das gewünschte Überschreibverhalten.)

F²F¹¹F¹¹F¹¹«

Schleife durch i) obere Zeilen und Körper k) Höhe l) Zeilen m) Spalten. (Durchlaufen Sie zuerst die oberen Zeilen und dann die Körper, um das Überschreiben von Körpern mit den oberen Zeilen zu vermeiden.)

J⁻⁻⁺λκ×μ³ι⁻λκ

Springe zur Position des Würfels.

≔§§θλμη

Ruft die Höhe in der aktuellen Zeile und Spalte ab.

¿∨⁼±η⊕κ‹κη

Testen Sie, ob für diese Zeile und Spalte ein Würfel in dieser Höhe gezeichnet werden soll.

¿ι“↗⊟&⁹κUhnI”___

Zeichne den Körper oder die Oberseite des Würfels.

Neil
quelle
Wenn ich die erste 3in eine ändere 33, bekomme ich nur 11 Blöcke im Turm. Im Allgemeinen scheinen die Türme auf 11 begrenzt zu sein. Wie passiert das?
Fabian Röling
@ Fabian Ich bin etwas verwirrt, das F¹¹F¹¹F¹¹war kein Hinweis ...
Neil
Ich kenne diese Programmiersprache nicht, ich habe nur ein bisschen mit dem TIO-Link rumgespielt.
Fabian Röling
30

C  376   350   313   309  285 Bytes

Vielen Dank an Jonathan Frech für das Speichern von vier Bytes!

#define F for(
char*t,G[26][67],*s;i,j,e,k,v,x,y;b(){F s="\\/__//\\__\\ ___ ";*s;--y,s+=5)F e=5;e--;*t=*s<33&*t>32?*t:s[e])t=G[y]+x+e;}f(int*M){F;e<1716;++e)G[e/66][e%66]=32;F k=0;++k<12;)F i=0;i<11;++i)F j=11;j--;v+k||b())x=i+j*3+k,y=14+i-k,(v=M[i*11+j])>=k&&b();F;++e<26;)puts(G+e);}

Probieren Sie es online!

Abgerollt:

#define F for(

char *t, G[26][67], *s;
i, j, e, k, v, x, y;

b()
{
    F s="\\/__//\\__\\ ___ "; *s; --y, s+=5)
        F e=5; e--; *t=*s<33&*t>32?*t:s[e])
            t = G[y]+x+e;
}

f(int*M)
{
    F; e<1716; ++e)
        G[e/66][e%66] = 32;

    F k=0; ++k<12;)
        F i=0; i<11; ++i)
            F j=11; j--; v+k||b())
                x = i+j*3+k,
                y = 14+i-k,
                (v=M[i*11+j])>=k && b();

    F; ++e<26;)
        puts(G+e);
}
Steadybox
quelle
Kann 26*66nicht sein 1716?
Jonathan Frech
@ JonathanFrech Klar, das habe ich vergessen.
Steadybox
*s==32-> *s<33.
Jonathan Frech
for(e=k=1;e;++k)for(e=-> for(k=1;e;++k)for(e=.
Jonathan Frech
#define B b(...)&++e-> #define B++e&b(...)(vorausgesetzt es bkommt nicht darauf an e, was ich glaube nicht).
Jonathan Frech
9

JavaScript (ES6), 277 251 Byte

a=>(n=55,$=f=>[...Array(n)].map((_,i)=>f(i)),S=$(_=>$(_=>' ')),n=11,$(l=>$(z=>$(y=>$(x=>(x=10-x,X=x*3+y+z,Y=y-z+n,Z=a[y][x])<=z&&Z+z+1?0:l?['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s)):S[Y].splice(X+1,3,...'___'))))),S.map(r=>r.join``).join`
`)

26 Bytes von @ Neils Vorschlag gespeichert .

Ungolfed

a=>(
    n=55,
    $=f=>[...Array(n)].map((_,i)=>f(i)),
    S=$(_=>$(_=>' ')),
    n=11,
    $(l=>
        $(z=>$(y=>$(x=>(
            x=10-x,
            X=x*3+y+z,
            Y=y-z+n,
            Z=a[y][x],
            Z<=z && Z+z+1 || (
                l
                ? ['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s))
                : S[Y].splice(X+1,3,...'___')
            )
        ))))
    ),
    S.map(r=>r.join``).join`\n`
)
darrylyeo
quelle
2
,$(w=>$(z=>$(y=>$(x=>(Z=a[y][x=10-x,X=x*3+y+z,Y=y-z+n,x])<=z&&Z+z+1?0:w?['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s)):S[Y].splice(X+1,3,...'___'))))),scheint 26 Bytes zu sparen.
Neil
@ Neil Brilliant! Das Zeichnen aller oberen Linien erspart mir die Suche nach Nicht-Leerzeichen.
Darrylyeo
6

Python 2 , 243 Bytes

a=input()
s=eval(`[[' ']*55]*23`)
for h in range(7986):
 k=h%3;x=h/3%11;y=h/33%11;z=h/363%11;i=h/3993;u=y+z-x*3+30;v=y-z+10
 if~-(z>=a[y][10-x]!=~z):
	if i*k:s[v+k][u:u+5]='\//\____/\\'[k%2::2]
	if~-i:s[v][u+1+k]='_'
for l in s:print''.join(l)

Probieren Sie es online!

Eine Python-Übersetzung von Neils Charcoal-Ansatz.

Lynn
quelle
Schön zu sehen, dass es dafür eine Python-Lösung gibt. Mein Python Proof-of-Concept war mehr als 900 Bytes!
James Holderness
3
+1+k-> -~k.
Jonathan Frech
5

Tcl, 380 bis 409 Bytes

User sergiol war damit beschäftigt, das sehr gut zu machen:

set X [read stdin]
proc L {a b c d e s} {time {incr z
set y -1
time {incr y
set x -1
time {if {abs([set Z [lindex $::X [expr ($y+1)*11-[incr x]-1]]])==$z|$z<$Z} {set s [string repl [string repl $s [set i [expr -3*$x+57*$y-55*abs($z)+701]] $i+$b $a] [incr i $c] $i+$e $d]}} 11} 11} 12
set s}
puts [L /\\__\\ 4 56 \\/__/ 4 [L "" -1 -55 ___ 2 [string repe [string repe \  55]\n 23]]]

Probieren Sie es online!

Ursprünglicher Inhalt

set xs [read stdin]
proc L {a b c d e s} {set z 0
while {[incr z]<12} {set y -1
while {[incr y]<11} {set x -1
while {[incr x]<11} {set Z [lindex $::xs [expr ($y+1)*11-$x-1]]
if {abs($Z)==$z||$z<$Z} {set i [expr -3*$x+57*$y-55*abs($z)+701]
set s [string repl [string repl $s $i $i+$b $a] [incr i $c] $i+$e $d]}}}}
set s}
puts [L /\\__\\ 4 56 \\/__/ 4 [L "" -1 -55 ___ 2 [string repe [string repe \  55]\n 23]]]

Probieren Sie es online!

Ach, es ist was es ist. Es ist nur ein bisschen leichter für die Augen, wenn "ungolfed"

set s [string repeat [string repeat " " 55]\n 23]

proc loops {s0 i0 io s1 i1} {
  set z  0; while {[incr z] < 12} {
  set y -1; while {[incr y] < 11} {
  set x -1; while {[incr x] < 11} {
    set Z [lindex $::xs [expr {($y+1) * 11 - $x - 1}]]
    if {abs($Z) == $z || $z < $Z} {
        set i [expr {-3*$x + 57*$y - 55*abs($z) + 701}]
        set ::s [string replace $::s $i $i+$i0 $s0]
        incr i $io
        set ::s [string replace $::s $i $i+$i1 $s1]
    }
  } } }
}

loops ""      -1 -55 \
       ___     2
loops /\\__\\  4  56 \
      \\/__/   4

puts $s

Erstellt eine Zeichenfolge gemäß den Anforderungen. Nimmt das Array von stdin. Geht von unten nach oben, von vorne nach hinten, von rechts nach links über die Zeichenfolgendaten. In zwei Durchgängen, einmal für die Oberkante und noch einmal für den Rest des Körpers jedes Würfels.

Ich habe versucht, es mit einem süßen funktionellen Lambda-Mojo zu verkleinern, aber das hat es leider größer gemacht.

Dúthomhas
quelle
Sie können Golf spielen: tio.run/…
sergiol
Weitere Golfplätze
sergiol
Mehr: tio.run/…
sergiol
Noch mehr: tio.run/…
sergiol
Noch mehr: tio.run/##lVHtboJAEPx/…
sergiol