Dibuja un cuboide ASCII

14

Dados tres enteros> = 2, cree un cubo ASCII en una proyección ortogonal (gabinete). Los tres enteros representan la altura, el ancho y la profundidad (medidos en caracteres visibles), incluidas las esquinas. Las esquinas deben ser 'o' o '+', libre elección.

w: 10, h: 5, d: 4 Así da:

   o--------o
  /        /|
 /        / |
o--------o  |
|        |  o
|        | /
|        |/
o--------o

Ahora, para hacer esto un poco más difícil, todas las caras pueden ser sólidas, transparentes o faltantes. Ordenamos las caras así:

   o--------o
  /        /|
 /    2   / |
o--------o 3|
|        |  o
|   1    | /
|        |/
o--------o

  ---
  |2|
-------
|5|1|3|
-------
  |4|
  ---
  |6|
  ---

Y proporcione una lista de tokens, S, T o M. El ejemplo original es así:

w 10
h 5
d 4
S S S S S S

   o--------o
  /        /|
 /        / |
o--------o  |
|        |  o
|        | /
|        |/ 
o--------o

Si una cara es transparente, podemos ver cualquier cosa que esté detrás de ella:

T S S S S S

   o--------o
  /        /|
 /        / |
o--------o  |
|  o-----|  o
| /      | /
|/       |/
o--------o


T T T T T T

   o--------o
  /|       /|
 / |      / |
o--------o  |
|  o-----|--o
| /      | /
|/       |/
o--------o

Para pares de caras faltantes, los bordes o esquinas adyacentes ya no son visibles:

M M S S S S

   o--------o
  /|       /|
 / |      / |
o  |     o  |
|  o-----|  o
| /      | /
|/       |/
o--------o

M M S S M S

   o--------o
   |       /|
   |      / |
   |     o  |
   o-----|  o
  /      | /
 /       |/
o--------o

Código de golf, el código más corto gana! Los espacios finales y las nuevas líneas están bien, puede elegir el método de entrada y el orden de entrada.

NiklasJ
fuente
55
¿Cuán estricto es su formato de entrada? ¿Puedo hacer una función con 9 parámetros?
LiefdeWen
1
@LiefdeWen you're free to choose input method and input order. Y como nada dice lo contrario, se puede usar cualquiera de los métodos de entrada / salida predeterminados .
dzaima
¿Puedo tomar un entero como mapa de bits para las banderas transparentes / sólidas?
Titus
@Titus Bueno ... está bien. Supongo que es un poco más entretenido si realmente puedes probar los valores por ti mismo.
NiklasJ

Respuestas:

5

De carbón , 190 181 bytes

NωA⁻ω²ςNηA⁻η²γNδA⁻δ²χA⪪S αF›⊟αMF⟦ςγςγ⟧«oκ↶»F∧›⊟αM²«oς↷³oχ↷¹»F∧›⊟αM²«↷³oχ↷³oγ↶»M⁻ωδ⁻δηF⁼§α²SG↗δ↓η↙δ↑η F∧›⊟αM²«↶¹oχ↷³oγ↷»F⁼§α¹SG↗δ←ω↙δ→ω F∧›⊟αM²«↶¹oχ↶³oς»F⁼§α⁰SUO±ωη ↷F›⊟αMF⟦γςγς⟧«oκ↷

Pruébalo en línea! El enlace es a la versión detallada del código. Editar: guardado 9 bytes al optimizar mis condiciones. El carbón no tiene elsetoken, por lo que los ifcomandos siempre tienen dos alternativas, a menos que estén al final de un bloque o programa. Para evitar esto, uso en for (<bool>)lugar de lo if (<bool>)cual tiene un efecto similar cuando la expresión solo puede tener los valores 0 o 1 pero guarda un byte. (Para lograr esto tuve que cambiar las expresiones de modo que siempre eran ciertas cuando el cuerpo necesita para ser ejecutado.) Yo también era capaz de optimizar if (<bool>) for (<int>)al for (And(bool, int)).

Neil
fuente
Santo Cristo O_O. Ni siquiera podía imaginar cómo dibujar el cubo usando carbón. ¿Puedes poner un ejemplo para dibujar un cubo simple en la carpeta de ejemplos de github? ¿Uno que ha sido optimizado? Quiero comparar mi respuesta de 50 bytes a lo que debería haber sido.
Magic Octopus Urn
@carusocomputing Lo siento, no tengo claro qué quiere decir con "cubo simple", y no soy un autor de Charcoal, por lo que no puedo agregar un ejemplo.
Neil
¿No lo eres? Santa mierda, ¿quién es? Sinceramente pensé que eras. Además, pediría ser un contribuyente de carbón. Podrías convertirte fácilmente en uno en github :). Eres talentoso en el idioma, obviamente. Y por "cubo simple" me refiero a la primera mitad del desafío, simplemente haciendo un X * Y * Z cubo ASCII.
Magic Octopus Urn
@carusocomputing ASCII-only es el principal contribuyente por lo que puedo decir, aunque el wiki de esolang acredita a un segundo contribuyente.
Neil
por lo menos me pondría en contacto con ellos con algunos de sus ejemplos, lo ha llevado más lejos que cualquier otra persona que haya visto. Me encantaría obtener más explicaciones de su código, he seguido sus respuestas de Charcoal por un momento porque el lenguaje es interesante para mí.
Magic Octopus Urn
2

JavaScript (ES6), 318 314 308 bytes

Toma ancho, alto y profundidad como enteros y las caras como una matriz de caracteres.

(w,h,d,l,M=(n,F)=>[...Array(n+1).keys()].map(F),a=M((L=w--+d)*(h--+--d),i=>++i%L?' ':`
`),D=(t,Y=0,X=d,W=t&1?d:w,H=t&2?d:h,F=l[t>>2])=>F>'R'&&M(W,i=>M(H,j=>a[p=L*(Y+j-i*(t&1))+X+i-(t&2?j:0)]=(x=!(i&&i-W)|2*!(j&&j-H))?' |-o|/o/-o'[t%4*3+x]:a[F>'S'?p:0])))=>D(20)&D(D(14,h)&D(17,d,0),d,D(9,d,w)&D(6))||a.join``

¿Cómo?

La función M () procesa una devolución de llamada F dada en un rango dado [0 ... n] .

M = (n, F) => [...Array(n + 1).keys()].map(F)

La variable a contiene una matriz plana que representa una cuadrícula de tamaño (w + d) x (h + d-1) . Inicialmente se llena con filas de espacios terminados con nuevas líneas.

a = M((L = w-- + d) * (h-- + --d), i => ++i % L ? ' ' : '\n')

La función D () se usa para 'dibujar' una cara del cuboide.

Los dos bits menos significativos del parámetro t contienen el tipo de cara:

  • 0 = trasero / delantero
  • 1 = izquierda / derecha
  • 2 = abajo / arriba

Los bits # 2 a # 4 contienen el índice de cara basado en 0.

D = (                                           // given:
  t, Y = 0, X = d,                              // - the type and the initial coordinates
  W = t & 1 ? d : w,                            // - the drawing width
  H = t & 2 ? d : h,                            // - the drawing height
  F = l[t >> 2]                                 // - the character representing the status
) =>                                            //
  F > 'R' &&                                    // provided that the face is not missing:
  M(W, i =>                                     // for each i in [0...W]:
    M(H, j =>                                   //  for each j in [0...H]:
      a[                                        //    update the output
        p = L * (Y + j - i * (t & 1)) +         //    at position p
            X + i - (t & 2 ? j : 0)             //
      ] =                                       //    with either:
      (x = !(i && i - W) | 2 * !(j && j - H)) ? //    - '|', '-' or '/' on edges
        ' |-o|/o/-o'[t % 4 * 3 + x]             //    - or 'o' on vertices
      :                                         //
        a[F > 'S' ? p : 0]                      //    - or a space on solid faces
    )                                           //    - or the current character on
  )                                             //      transparent faces

Las caras se dibujan en el siguiente orden:

D(5 * 4 + 0, 0, d)  // face #5 (rear)
D(3 * 4 + 2, h, d)  // face #3 (bottom)
D(4 * 4 + 1, d, 0)  // face #4 (left)
D(2 * 4 + 1, d, w)  // face #2 (right)
D(1 * 4 + 2, 0, d)  // face #1 (top)
D(0 * 4 + 0, d, 0)  // face #0 (front)

Manifestación

Arnauld
fuente
1

SOGL v0.11 , 200 194 193 192 190 bytes

b³@*⁶
ž}1}X⁵
;aκ⁴
2-³
* o1Ο²
d=?a³:?∫:¹
be.Aā6∫D,ζLI%:C?abe"DCa∫:c+H⁴d+ /ž}{"a+Hy"e³┐²čž|"b³┌²žz"EBAøp”,ōkB°s9θW=*↑(⅜⅞~υ=\⁰ōwūΧ►ΣΤP░¶Ο⁽◄Φ7⅟▲s#‘┌Θdwι+#¶ŗ!!6c=?6d=?2aI⁶e³∙ž}5¹b+⁴Ie³@∙⁵}4¹2+⁴⁶⁵

Toma entrada en el orden

width
height
depth
down-face
left-face
back-face
top-face
right-face
front-face

¡Atado!
Pruébalo aquí! (el valor comprimido cambió para ser compatible con V0.12)

dzaima
fuente