Extrudez les faces d'un cube symétriquement le long de XYZ

33

bac à sable

Pour les besoins de la tâche en cours, un cube de longueur unitaire est rendu en projection oblique avec des symboles ASCII comme suit:

  +-----+
 /     /|
+-----+ |
|     | +
|     |/
+-----+
  • + pour les sommets.
  • -pour les X bords. L'unité de longueur le long de X est représentée par cinq -entre deux sommets.
  • |pour les bords en Y. L'unité de longueur le long de Y est représentée par deux |entre deux sommets.
  • /pour les bords Z. L'unité de longueur le long de Z est représentée par une /entre deux sommets.
  • Les sommets ne sont tracés que là où les trois plans se coupent.
  • Les bords ne sont dessinés que là où exactement deux plans se croisent.

Lorsqu'une face d'unité est extrudée, elle est décalée d'une longueur d'unité par rapport à sa position d'origine et quatre nouvelles arêtes sont créées pour chaque direction (positive et négative).

Vous pouvez imaginer que l'extrusion consiste à dessiner les axes d'un système de coordonnées cartésien 3D, chaque axe étant représenté par un cuboïde avec une section transversale de 1x1 et une ndistance de (0,0,0).

Extrudé par 1 le long de X:

  +-----------------+
 /                 /|   
+-----------------+ |
|                 | +
|                 |/
+-----------------+

Tâche

A partir de trois nombres pour les axes XYZ, extrudez les faces d'un cube unité de manière symétrique par les quantités indiquées et restituez le résultat avec les symboles ASCII comme spécifié ci-dessus.

Contribution

x, y, z - nombres non négatifs - longueurs d'extrusion pour les axes respectifs. 0 signifie pas d'extrusion. L'entrée peut être trois chiffres, une liste de trois chiffres, un triple, une chaîne ou tout ce qui vous convient.

Sortie

Le dessin ASCII du cube après extrusion. Les espaces libres de début et de fin sont autorisés.

Cas de test

X Y Z
0 0 0

  +-----+
 /     /|
+-----+ |
|     | +
|     |/
+-----+

1 0 0

  +-----------------+
 /                 /|   
+-----------------+ |
|                 | +
|                 |/
+-----------------+


0 0 1   
        +-----+
       /     /|
      /     / |
     /     /  +
    /     /  /
   /     /  /
  +-----+  /
  |     | / 
  |     |/
  +-----+


1 1 0

        +-----+
       /     /|      
      +-----+ |
  +---|     | +-----+
 /    |     |/     /|
+-----+     +-----+ |
|                 | +
|                 |/
+-----+     +-----+
      |     | +
      |     |/
      +-----+

2 0 1

                +-----+
               /     /|
  +-----------+     +-----------+
 /                             /|
+-----------+     +-----------+ |
|          /     /|           | +
|         +-----+ |           |/
+---------|     | +-----------+
          |     |/
          +-----+

1 1 1 

        +-----+
       /     /|-+   
      +-----+ |/|
  +---|     | +-----+
 /    |     |/     /|
+-----+-----+-----+ |
|    /     /|     | +
|   +-----+ |     |/
+---|     | +-----+
    |     |/| +
    +-----+ |/
      +-----+

Critères gagnants

La solution la plus courte en octets dans toutes les langues gagne. Veuillez ajouter une brève description de la méthode utilisée et votre code.

Galen Ivanov
la source
Existe-t-il une limite supérieure pour chacune des extrusions?
Incarnation de l'Ignorance
@Embodiment of Ignorance - 9 devrait suffire
Galen Ivanov

Réponses:

14

JavaScript (ES6),  525 ... 475 471  459 octets

13 octets sauvés grâce à @Neil

Prend les entrées sous forme de tableau [X,Y,Z]. Retourne une matrice de caractères.

a=>([X,Y,Z]=a,m=[],W=X*6+Z*2,'1uol9h824lsqpq17de52u1okgnv21dnjaww111qmhx1gxf4m50xg6pb42kzijq21xyh34t0h2gueq0qznnza2rrimsg3bkrxfh3yrh0em').replace(/.{7}/g,s=>[[c,x,A,y,B,w,C,h,D,t]=parseInt(s,36)+s,Y*W,Z,X,Y|!W,Z*X,X*Y*!Z,X*Z*!Y,Y*Z*!X][c]&&(g=H=>V<h&&((m[r=y-(3-B)*p+(t>1?H-V:V)+Y*3+Z*2]=m[r]||Array(W*2+9).fill` `)[x-2*(3-A)*p+(t>1?V:H-V*t)+W]=` ${c>5?'  + ':t>1?'|-':'-|'}+/+`[(H%~-w?0:+t?4:2)|!(V%~-h)],g(++H<w?H:!++V)))(V=0,p=a[c%3],w-=-3*C*p,h-=-D*p))&&m

Essayez-le en ligne!

Comment?

Étapes de dessin

La sortie comprend 15 côtés, dessinés dans un ordre spécifique.

animation

la mise en oeuvre

La fonction de dessin est g . Cela fonctionne avec les paramètres suivants:

  • (x,y) : par où commencer à dessiner
  • w : largeur
  • h : hauteur
  • t : type de côté

Les sommets sont toujours dessinés. Selon la valeur d'un autre paramètre c , les arêtes sont dessinées ou effacées.

Si t=0 , la fonction dessine une face avant:

...........      ...........
..+-----+..      ..+     +..
..|     |..  or  ..       ..
..|     |..      ..       ..
..+-----+..      ..+     +..
...........      ...........

Si t=1 , il dessine un côté supérieur:

...........      ...........
...+-----+.      ...+     +.
../     /..  or  ..       ..
.+-----+...      .+     +...
...........      ...........

t=2

......+....      ......+....
...../|....      .....  ....
....+ |....  or  ....+  ....
....| +....      ....  +....
....|/.....      ....  .....
....+......      ....+......

(x,y)(w,h)XYZ

c[1..8]

Pour résumer, un côté est complètement décrit avec:

{ctx=ox+mx×Py=oy+my×Pw=ow+mw×Ph=oh+mh×P

Pc

Par conséquent, nous devons stocker les 10 paramètres suivants pour chaque côté:

[c,ox,mx,oy,my,ow,mw,oh,mh,t]

Vous trouverez ci-dessous les paramètres des 15 côtés à dessiner:

sidecoxmxoymyowmwohmht0400237046014602346302226222403423366204030243062071240052220270341632600712301720222704008562224012294200370301101002370130111602313302126002070400137200070301148602040302

[0..9]

mx(mx+6)/2mymy+3mwmw/3

Il en résulte 15 chiffres d’exactement 10 chiffres décimaux, qui sont stockés dans 15 groupes de 7 chiffres en base 36.

Par exemple, le premier côté est codé 4032070460et stocké sous 1uol9h8.

Arnauld
la source
Je pense Array(W*2+9).fill` ` sauve un octet.
Neil
Oups, désolé, mon mauvais, je dois l'avoir vu mal ou quelque chose. Mépris.
Incarnation de l'Ignorance
@EmbodimentofIgnorance Pas de soucis. :)
Arnauld
3
Excellente visualisation en plus de votre description traditionnellement cool! Le respect!
Galen Ivanov
@GalenIvanov Merci! J'ai vraiment aimé travailler sur ce défi.
Arnauld
13

APL (Dyalog Classic) , 162 161 132 130 octets

{' |+/+ +-? ??? ++'[⍉(⊃~∘0)⍤13⍉↑a↑¨⍨↓(--1-⌊/∘,)2-/1⌽↑⍳⍴a←16|29|1+{2⊥+/¨∊¨=⌿¨⍵(⍉⍵)(⍉↓⍵)}⌺2 2 2{⍉⍤2⍉⌽0,⍵}⍣63/↓2/61<⍵+.=⍨↑⍳1+2×⍵]}

Essayez-le en ligne!

  • générer un tableau 3D bool de cubes d'unités
  • répliquer chaque cube 6 3 2 fois le long de xyz
  • entourer de zéros
  • pour chaque 2 x 2 x 2 sous - matrice calculer un nombre compris entre 0 et 16 qui détermine le produit de carbonisation de sortie correspondant: (1 + 4*cx + 2*cy + cz) mod 16cx, cy, czsont le nombre de même valeur « tiges » le long de l' axe x, y, z, à savoir des vecteurs le long de cet axe qui se composent de la même valeur: 0 0 ou 1 1. Nous faisons une exception si le sous-tableau est tout à zéro (ou tout à un - ceux qui comptent n'a pas d'importance) et nous considérons son nombre 0 au lieu de 28
  • pour chaque cellule calculer où le caractère correspondant doit être dessiné à l'écran
  • pour chaque cellule, construisez une matrice transparente (à remplissage 0) contenant un seul "pixel" opaque
  • mélangez les matrices - à ce stade, nous avons un tableau 5d de dimensions inx, iny, inz, outx, outy
  • réduire les trois premiers axes en ne conservant que le premier élément non transparent (0)
  • utiliser une table de correspondance (une chaîne) pour convertir les nombres en -|/+

Merci Scott Milner pour repérer que certains +s rendus comme ?s

ngn
la source
Comment testez-vous cela? Je voulais essayer des extrusions de 2,3,4 par exemple, mais rien d’évident ne semblait fonctionner.
Neil
l'algo gaspille beaucoup de mémoire, donc 2 3 4 manque de mémoire, mais 2 3 3 est à portée de main
ngn
@ Neil j'ai fait un petit correctif et maintenant 2 3 4 fonctionne. perdu un octet en tant qu'effet secondaire :)
ngn
Une solution APL deux fois moins longue qu'une solution charbon de bois sur un défi artistique ?! Que se passe-t-il?!
Shaggy
3
Pas sûr à 100%, mais je suis à peu près sûr que ce n'est pas le comportement souhaité le 0 1 1
Scott Milner
6

Charbon de bois , 325 octets

≔×⁶Nθ≔׳Nη≔⊗Nζ¿‹¹№⟦θηζ⟧⁰«B⁺⁷⊗θ⁺⁴⊗η↗↗⊕⊗ζ+⁺⁵⊗θP↙⊗⊕ζ↓+↓⁺²⊗η↙+↙⊕⊗ζ»«F‹⁰θ«↗+↗←+←⊖θ↙+/P→θ↓+↓²+⊖θ+»F‹⁰η«J⁶¦³↗+↗↓+↓⊖η↙+/P↑η←+←⁵↑+↑⊖η+»F‹⁰ζ«J⁸±²↓+↓↓↗+↗⊖ζ↑+↑²P↙ζ←+←⁵↙+↙⊖ζ+»J⁶¦⁰F‹⁰ζ«G↓³↙⊕ζ←⁷↑³↗⊕ζ ↙+↙⊖ζ↓+↓²+→⁵P↗ζ↑+↑²P←⁶↗+↗⊖ζ»F‹⁰η«G←⁶↑⊕η↗³→⁶↓⊕η ↑+↑⊖η←+←⁵↙+/P↓η+⁵P↗²↓+↓⊖η»F‹⁰θ«G↗²→⊕θ↓⁴↙²←⊕θ →+⊖θ↗+/↑+↑²P←θ↙+/P↓³←+←⊖θ»P↗∧∧θη²P↓∧∧ζθ³P←∧∧ηζ⁶+

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

≔×⁶Nθ≔׳Nη≔⊗Nζ

Entrez les extrusions, mais prémultipliez-les pour économiser des octets.

¿‹¹№⟦θηζ⟧⁰«B⁺⁷⊗θ⁺⁴⊗η↗↗⊕⊗ζ+⁺⁵⊗θP↙⊗⊕ζ↓+↓⁺²⊗η↙+↙⊕⊗ζ»«

Si au moins deux des extrusions sont nulles, tracez simplement un cuboïde de dimensions (2x + 1, 2y + 1, 2z + 1). Autrement:

F‹⁰θ«↗+↗←+←⊖θ↙+/P→θ↓+↓²+⊖θ+»

Imprimer l'extrusion de gauche, le cas échéant.

F‹⁰η«J⁶¦³↗+↗↓+↓⊖η↙+/P↑η←+←⁵↑+↑⊖η+»

Imprimez l'extrusion vers le bas, le cas échéant.

F‹⁰ζ«J⁸±²↓+↓↓↗+↗⊖ζ↑+↑²P↙ζ←+←⁵↙+↙⊖ζ+»

Imprimer l'extrusion arrière, le cas échéant.

J⁶¦⁰

Les extrusions restantes se rencontrent toutes à ce stade (qui ne sera pas tiré avant la fin!)

F‹⁰ζ«G↓³↙⊕ζ←⁷↑³↗⊕ζ ↙+↙⊖ζ↓+↓²+→⁵P↗ζ↑+↑²P←⁶↗+↗⊖ζ»

Imprimez les extrusions avant, le cas échéant, en prenant soin d’effacer les parties des extrusions gauche et inférieure qui peuvent se chevaucher.

F‹⁰η«G←⁶↑⊕η↗³→⁶↓⊕η ↑+↑⊖η←+←⁵↙+/P↓η+⁵P↗²↓+↓⊖η»

Imprimez l’extrusion, le cas échéant, en prenant soin d’effacer les parties du dos et les extrusions laissées qui peuvent se chevaucher.

F‹⁰θ«G↗²→⊕θ↓⁴↙²←⊕θ →+⊖θ↗+/↑+↑²P←θ↙+/P↓³←+←⊖θ»

Imprimez la bonne extrusion, le cas échéant, en prenant soin d’effacer les parties des extrusions vers le bas et vers le bas qui peuvent se chevaucher.

P↗∧∧θη²P↓∧∧ζθ³P←∧∧ηζ⁶+

Dessinez les jointures entre ces dernières extrusions.

Neil
la source
325 octets de charbon de bois?! Sur un défi d' art ascii ?! C'est assez pour que je ne tente même pas ceci en Ja (vaScri) pt!
Shaggy
@ Shaggy Ce n'est peut-être pas une approche optimale, et il y a peut-être des façons de jouer au golf que j'ai de toute façon négligé. Je dois dire cependant que la méthode de ngn a l'air intrigante, il semble qu'il dessine la forme dans un tableau interne, puis effectue une détection de bord pour générer sa sortie.
Neil
@Shaggy, j'ai proposé une solution de 195 octets, que j'ai publiée séparément car il s'agit d'une approche complètement différente. Reste bien loin de APL cependant.
Neil
3

Charbon de bois , 195 164 144 octets

≔⁺³×⁶Nθ≔⁺²×³Nη≔⊕⊗NζF…·±ζζF…·±ηηF…·±θθ«J⁻λι⁺κι≔⟦⟧δFE²↔⁻⁺ιμ·⁵FE²↔⁻κνFE²↔⁻⁺λξ·⁵⊞δ⌊⟦‹μζ‹νη‹ξθ‹¹№E⟦μνξ⟧‹π⊕ρ¹⟧≡Σδ¹+²§ |-/⁺⌕δ¹⌕⮌δ¹¦³+⁴§ +Σ…δ⁴¦⁶§ |-/⌕δ⁰

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Je publie cette réponse séparément, car elle utilise une approche complètement différente pour dessiner l'extrusion. Explication:

≔⁺³×⁶Nθ≔⁺²×³Nη≔⊕⊗Nζ

Entrez les extrusions et calculez la moitié de la taille du cuboïde englobant, mais en arithmétique sur nombres entiers, car les plages de Charcoal sont toujours des entiers. L'origine de la sortie est mappée sur le centre du cube d'unité d'origine.

F…·±ζζF…·±ηηF…·±θθ«

Boucle sur toutes les coordonnées à l'intérieur (y compris la limite) du cuboïde contenant l'extrusion.

J⁻λι⁺κι

Aller à la position de sortie correspondant à ces coordonnées.

≔⟦⟧δFE²↔⁻⁺ιμ·⁵FE²↔⁻κνFE²↔⁻⁺λξ·⁵⊞δ⌊⟦‹μζ‹νη‹ξθ‹¹№E⟦μνξ⟧‹π⊕ρ¹⟧

À partir des coordonnées indiquées, examinez les huit directions en diagonale afin de déterminer si l’extrusion se chevauche dans cette direction. Les coordonnées détectées sont vérifiées dans le cuboïde, puis le nombre d'axes dans lesquels la coordonnée se trouve dans le cube d'origine doit être supérieur à 1. Notez que, comme le cube a une hauteur d'affichage impaire, les valeurs de l'axe Y qui sont regardés sont des entiers tandis que les autres axes utilisent des coordonnées fractionnaires.

≡Σδ

Considérez le nombre de directions dans lesquelles l'extrusion se chevauche. Il y a cinq cas d’intérêt où nous voulons imprimer quelque chose, comme dans le cas de zéro, cela signifie que c’est un espace vide et que nous ne voulons rien imprimer, alors que dans le cas de huit, cela signifie que c’est à l’intérieur. l'extrusion et tout ce que nous avons imprimé seraient surimprimés par une couche plus proche du point de vue.

¹+

Si l'extrusion ne se chevauche que dans une direction, il s'agit d'un coin externe et nous devons générer un +.

²§ |-/⁺⌕δ¹⌕⮌δ¹¦

Si l'extrusion se chevauche dans deux directions, il s'agit d'un bord extérieur. Quelle sorte d'arête est déterminée à partir de la séparation entre les deux chevauchements; 6 et 7 sont des bords tournés vers l'arrière et seront écrasés, 4 est un bord diagonal, 2 est un bord vertical et 1 est un bord horizontal. (En fait, je calcule 7 moins la séparation car cela semble être plus facile à faire.)

³+

Si l'extrusion se chevauche dans trois directions, il s'agit d'un coin interne dans le cas où l'une des extrusions est égale à zéro et que nous devons générer un +.

⁴§ +Σ…δ⁴¦

Si l'extrusion se chevauche dans quatre directions, il y a deux cas: les faces (toutes directions) et les angles intérieurs dans le cas de trois extrusions positives. Dans ce dernier cas, il existe un nombre impair de chevauchements vers le spectateur.

⁶§ |-/⌕δ⁰

Si l'extrusion se chevauche dans six directions, il s'agit d'un bord intérieur. Cela fonctionne comme le complément d'un bord extérieur, sauf que nous ne sommes intéressés que lorsqu'un des deux espaces vides est la direction vers le point de l'oeil (la dernière entrée du tableau).

Neil
la source
2

K (ngn / k) , 172 octets

{s:1+|/'i-:&//i:1_--':1_4#!#'2*:\a:16!29!1+2/(!3){+'+x}/'{2+':''1+':'0=':x}'{++'x}\6{+'+0,|x}/{6}#{3}#'{2}#''s#1<+/x=!s:1+2*x;" |+/+ +-? ??? ++"s#@[&*/s;s/i;{x+y*~x};,//a]}

Essayez-le en ligne!

réécriture k obligatoire de ma solution apl

Même algorithme, sauf que le rendu 3d-> 2D est réalisé avec (l'équivalent de k) d'affectation d'indice de dispersion au lieu de créer des matrices 2D pour chaque élément 3D et de les mélanger.

ngn
la source
Quelle serait votre ngn/aplperformance par rapport à votre Dyalog APLsolution?
Galen Ivanov
@GalenIvanov ce ne serait pas une comparaison juste parce que dans ma solution d'apl, je perds beaucoup de mémoire pour économiser quelques octets, et dans k plus court, il s'avère plus rapide dans ce cas
ngn
J'ai demandé à propos de la comparaison entre deux solutions APL - la vôtre APL / Dyalog et une solution hypothétique dans ngn / apl
Galen Ivanov
oups, je ne sais pas pourquoi j'ai lu cela comme "ngn / k" ... c'est encore injuste - ngn / apl est amateur javascript, dyalog est professionnel c
ngn
1
@GalenIvanov probablement pas. ngn / apl manque des ajouts récents à la langue comme l'opérateur de rang ( ) et le stencil ( )
ngn