Bâtiment de blocs 3D ASCII

82

Défi

Ecrivez un programme qui prend un tableau d'entiers 11x11 et construit un bloc de construction 3D ASCII, où chaque valeur du tableau représente la hauteur d'une colonne de blocs aux coordonnées correspondant à la position du tableau. Une hauteur négative est une colonne "flottante" - seul le bloc supérieur est visible.

Exemple

                                                        __________________
                                        ___            /\__\__\__\__\__\__\
 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,           \/\__\   \/__/__/__/__/       \/\__\
                                             \/\__\_________         ______\/\__\
                                              \/\__\__\__\__\       /\__\__\__\__\
                                               \/__/__/__/__/       \/__/__/__/__/

Contribution

L'entrée sera une liste de 121 nombres entiers, soit lus à partir de stdin (le choix du séparateur dépend de vous), soit transmis sous forme de tableau (peut être 1D ou 2D).

Les hauteurs seront comprises entre -11 et 11.

Sortie

Le bâtiment généré peut être écrit sur stdout, affiché directement à l'écran ou renvoyé sous forme de chaîne séparée par une nouvelle ligne.

Les espaces de début et de fin sont autorisés.

Règles de construction

La forme d'un bloc 3D individuel ressemble à ceci:

 ___
/\__\
\/__/

Et un cube de blocs 2x2x2 ressemble à ceci:

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

Lorsque des blocs se chevauchent, un bloc supérieur a priorité sur un bloc inférieur, les blocs situés en avant ont priorité sur ceux situés plus en arrière et les blocs situés à gauche ont priorité sur ceux situés à droite. Le seul cas particulier est que la ligne supérieure d'un bloc ne doit jamais écraser un caractère autre qu'un espace derrière ce dernier.

L’interprétation des hauteurs de colonne s’explique le mieux en regardant une représentation 2D du côté.

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

Cas de test

Si vous souhaitez essayer votre solution sur quelques entrées supplémentaires, j'ai mis en place quelques cas de test ici .

Gagnant

C'est du , donc la soumission la plus courte (en octets) gagne.

James Holderness
la source
9
Oh, mon garçon, préparez-vous pour des solutions de plus de 300 octets. Bon challenge. +1
totalement humain
7
@totallyhuman Nah, Dennis va avoir une solution à 9 octets pour cela dans 20 minutes.
Deacon
3
La perspective doit-elle être identique à celle indiquée en bas à gauche des données d'entrée au premier plan? Le fait qu'il ne s'agisse pas du premier ou du dernier élément de données rend la tâche plus difficile. Est-il acceptable soit de 1. garder le mappage tel quel et d’obtenir une sortie avec la colonne en bas à droite au premier plan ou 2. de dessiner une image miroir ou une rotation de 90 degrés des données? Dans l'un ou l'autre cas, le dernier élément de données correspondrait à la colonne au premier plan, ce qui serait plus facile.
Level River St
3
Je suis enclin à utiliser un vrai moteur de jeu (ou une partie de celui-ci) pour restituer une photo et la convertir au format ASCII
Stan Strum
@LevelRiverSt Cela semble être une demande raisonnable. Vous pouvez choisir l'ordre des 121 éléments d'entrée comme étant le plus logique pour votre solution, à condition que votre commande soit cohérente. Il doit être possible de produire tout type de mise en page pouvant être produit avec l'ordre par défaut.
James Holderness

Réponses:

25

Charbon de bois , 70 69 68 octets

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Explication:

≔E¹¹⮌I⪪S,θ

Lisez le tableau, divisez chaque ligne en virgules et transformez-le en entier, mais inversez également chaque ligne, car nous souhaitons dessiner de droite à gauche afin que les colonnes de gauche remplacent les colonnes de droite. (Les autres dimensions ont déjà le comportement de réécriture souhaité.)

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

Boucle entre i) les lignes du haut et les corps k) hauteur l) rangées m) colonnes. (La boucle entre les premières lignes du haut, puis les corps évite d’écraser les corps avec les lignes du haut.)

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

Aller à la position du cube.

≔§§θλμη

Récupère la hauteur à la ligne et à la colonne en cours.

¿∨⁼±η⊕κ‹κη

Testez si un cube doit être dessiné à cette hauteur pour cette ligne et cette colonne.

¿ι“↗⊟&⁹κUhnI”___

Dessine le corps ou le haut du cube.

Neil
la source
Quand je change le premier 3en a 33, je n'ai que 11 blocs dans la tour. En général, les tours semblent être plafonnées à 11. Comment cela se produit-il?
Fabian Röling
@Fabian Je suis un peu confus que ce F¹¹F¹¹F¹¹n'était pas un indice ...
Neil
Je ne connais pas ce langage de programmation, je viens de jouer un peu avec le lien TIO.
Fabian Röling
30

C,  376   350   313   309  285 octets

Merci à Jonathan Jonathan Frech d'avoir économisé quatre octets!

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

Essayez-le en ligne!

Déroulé:

#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
la source
Ne peut 26*66pas être 1716?
Jonathan Frech
@ JonathanFrech Bien sûr, j'ai oublié à ce sujet.
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(...)(en supposant que bcela ne dépende pas de ece que je pense, non).
Jonathan Frech
9

JavaScript (ES6), 277 251 octets

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

Sauvegardé 26 octets de la suggestion de @ Neil .

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
la source
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,...'___'))))),semble économiser 26 octets.
Neil
@ Neil Brilliant! Dessiner d'abord toutes les lignes du haut m'évite de chercher des espaces.
darrylyeo
6

Python 2 , 243 octets

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)

Essayez-le en ligne!

Une traduction en Python de l'approche charbon de Neil.

Lynn
la source
C'est bien de voir une solution Python au golf pour cela. Ma preuve de concept Python comptait plus de 900 octets!
James Holderness le
3
+1+k-> -~k.
Jonathan Frech
5

APL (Dyalog Unicode) , 117 116 112 octets SBCS

a23 550⋄{i11 0+⍵+.×3 23-7897⊤⍨65⋄(,2 5ia)←745366⊤⍨104⋄(3i1⌽¯1a)⌈←1j[⍋-/↑j←⍸↑⎕↑¨⊂⌽1,11/2]⋄' _/\'[a]

Essayez-le en ligne!

ngn
la source
5

Tcl, 380 409 octets

L'utilisateur sergiol a été très occupé à résoudre ce problème :

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

Essayez-le en ligne!

Contenu original

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

Essayez-le en ligne!

Hélas, c'est ce que c'est. Ce n'est qu'un peu plus facile pour les yeux quand il est «non-golfé»

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

Construit une chaîne, selon les exigences. Prend le tableau de stdin. Va de bas en haut, d'avant en arrière, de droite à gauche sur les données de la chaîne. Le fait en deux passes, une pour le bord supérieur et une autre pour le reste du corps de chaque cube.

J'ai essayé de le rendre plus petit en utilisant du lambda mojo doux et fonctionnel, mais hélas, cela l'a rendu plus grand.

Dúthomhas
la source
Vous pouvez jouer au
sergiol
Plus de golf: tio.run/…
sergiol
Plus: tio.run/…
sergiol
Encore plus: tio.run/…
sergiol
Plus encore: tio.run/##lVHtboJAEPx/…
sergiol