Desenhar um cubóide ASCII

14

Dado três números inteiros> = 2, crie um cubo ASCII em uma projeção ortogonal (gabinete). Os três números inteiros representam altura, largura e profundidade (medidos em caracteres visíveis), incluindo os cantos. Os cantos devem ser 'o's ou' + ', de livre escolha.

w: 10, h: 5, d: 4 Dá assim:

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

Agora, para tornar isso um pouco mais difícil, todas as faces podem ser sólidas, transparentes ou ausentes. Nós ordenamos os rostos assim:

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

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

E forneça uma lista de tokens, S, T ou M. O exemplo original é assim:

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

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

Se um rosto é transparente, podemos ver qualquer coisa por trás dele:

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 faces ausentes, arestas ou cantos adjacentes não são mais visíveis:

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 golfe, código mais curto ganha! Espaços à direita e novas linhas são bons, você pode escolher o método e a ordem de entrada.

NiklasJ
fonte
5
Quão rigoroso é o seu formato de entrada? posso fazer uma função com 9 parâmetros?
LiefdeWen
1
@LiefdeWen you're free to choose input method and input order. E como nada diz o contrário, qualquer um dos métodos de entrada / saída padrão pode ser usado.
dzaima
Posso usar um número inteiro como bitmap para os sinalizadores transparentes / sólidos?
Titus
@ Titus Bem .. tudo bem. Eu acho que é um pouco mais divertido se você realmente pode testar os valores por si mesmo.
NiklasJ

Respostas:

5

Carvão , 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κ↷

Experimente online! Link é a versão detalhada do código. Editar: salvou 9 bytes otimizando minhas condições. O carvão não tem elsetoken, portanto, os ifcomandos sempre têm duas alternativas, a menos que estejam no final de um bloco ou programa. Para evitar isso, uso em for (<bool>)vez de if (<bool>)que tenha um efeito semelhante quando a expressão pode ter apenas os valores 0 ou 1, mas salva um byte. (A fim de conseguir isso eu tive que mudar as expressões de modo que eles estavam sempre verdadeiro quando o corpo precisava ser executado.) I também foi capaz de otimizar if (<bool>) for (<int>)para for (And(bool, int)).

Neil
fonte
Santo Cristo O_O. Eu não conseguia nem descobrir como desenhar o próprio cubo usando carvão. Você pode colocar um exemplo para desenhar um cubo simples na pasta de exemplos do github? Um que foi otimizado? Quero comparar minha resposta de 50 bytes como o que deveria ter sido.
Magic Octopus Urn
@carusocomputing Desculpe, não sei ao certo o que você quer dizer com "cubo simples", e não sou autor do próprio carvão, por isso não posso adicionar um exemplo.
Neil
Você não é ?! Caramba, quem é? Sinceramente, pensei que você fosse. Além disso, eu pediria para ser um colaborador de carvão. Você pode facilmente se tornar um no github :). Você é talentoso no idioma, obviamente. E por "cubo simples", quero dizer a primeira metade do desafio, apenas criando um X * Y * Z cubo ASCII.
Magic Octopus Urn
@carusocomputing ASCII-only é o principal contribuinte, tanto quanto posso dizer, embora o wiki da esolang credite um segundo colaborador.
Neil
no mínimo, eu os contataria com alguns de seus exemplos, você foi além do que qualquer outra pessoa que já vi. Gostaria muito de obter mais explicações sobre seu código. Segui suas respostas sobre carvão agora, porque a linguagem é interessante para mim.
Magic Octopus Urn
2

JavaScript (ES6), 318 314 308 bytes

Toma largura, altura e profundidade como números inteiros e as faces como uma 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``

Quão?

A função M () processa um dado retorno de chamada F em um determinado intervalo [0 ... n] .

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

A variável a possui uma matriz plana que representa uma grade de tamanho (w + d) x (h + d-1) . Inicialmente, é preenchido com linhas de espaços terminadas com novas linhas.

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

A função D () é usada para 'desenhar' uma face do cubóide.

Os dois bits menos significativos do parâmetro t contêm o tipo de face:

  • 0 = traseira / frente
  • 1 = esquerda / direita
  • 2 = inferior / superior

Os bits 2 a 4 mantêm o índice de face com base em 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

As faces são desenhadas na seguinte ordem:

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)

Demo

Arnauld
fonte
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+⁴⁶⁵

Recebe entrada na ordem

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

Amarrado!
Experimente aqui! (valor compactado alterado para ser compatível com V0.12)

dzaima
fonte