Edifício de bloco ASCII 3D


82

Desafio

Escreva um programa que utilize uma matriz 11x11 de números inteiros e construa uma construção de bloco ASCII 3D, em que cada valor na matriz represente a altura de uma coluna de blocos nas coordenadas correspondentes à posição da matriz. Uma altura negativa é uma coluna "flutuante" - apenas o bloco superior é visível.

Exemplo

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

Entrada

A entrada será uma lista de 121 números inteiros, lida a partir de stdin (a escolha do separador é sua) ou transmitida como uma matriz (pode ser 1D ou 2D).

As alturas estarão no intervalo de -11 a 11.

Resultado

A construção gerada pode ser gravada em stdout, exibida diretamente na tela ou retornada como uma sequência separada por nova linha.

Os espaços em branco à esquerda e à direita são permitidos.

Regras de construção

A forma de um bloco 3D individual é assim:

 ___
/\__\
\/__/

E um cubo 2x2x2 de blocos é assim:

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

Quando os blocos se sobrepõem, um bloco mais alto tem precedência sobre o mais baixo, os blocos da frente têm precedência sobre os que estão mais atrás, e os blocos à esquerda têm precedência sobre os da direita. O único caso especial é que a linha superior de um bloco nunca deve sobrescrever nenhum caractere não espacial por trás dele.

A interpretação das alturas das colunas pode ser melhor explicada olhando-se uma representação 2D do lado.

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

Casos de teste

Se você quiser experimentar sua solução com mais algumas entradas, reuni alguns casos de teste aqui .

Ganhando

Isso é , então o envio mais curto (em bytes) vence.


9
Oh, garoto, prepare-se para mais de 300 soluções de bytes. Bom desafio. +1
totallyhuman 12/01

7
@totallyhuman Nah, o Dennis terá uma solução de 9 bytes para isso em 20 minutos.
Deacon

3
A perspectiva precisa ser a mostrada na parte inferior esquerda dos dados de entrada em primeiro plano? O fato de esse não ser o primeiro ou o último elemento dos dados dificulta. É aceitável 1. manter o mapeamento como está e desenhar a saída com a coluna inferior direita em primeiro plano ou 2. desenhar uma imagem espelhada ou rotação de 90 graus dos dados? Qualquer um deles faria o último elemento de dados corresponder à coluna em primeiro plano, o que seria mais fácil.
Level River St

3
Sinto-me inclinado a usar um motor de jogo real (ou parte dele) para tornar uma foto e convertê-lo em ASCII
Stan Strum

@LevelRiverSt Parece uma solicitação razoável - você pode escolher a ordem dos 121 elementos de entrada como o que fizer mais sentido para a sua solução, desde que a sua encomenda seja consistente. Deve ser possível produzir todo tipo de layout que pode ser produzido com o pedido padrão.
James Holderness

Respostas:


25

Carvão , 70 69 68 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

≔E¹¹⮌I⪪S,θ

Leia o array, divida cada linha em vírgulas e converta em número inteiro, mas também inverta cada linha, pois queremos desenhar da direita para a esquerda para que as colunas da esquerda substituam as da direita. (Outras dimensões já possuem o comportamento de substituição desejado.)

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

Loop através de i) linhas e corpos superiores k) altura l) linhas m) colunas. (Fazer um loop nas primeiras linhas principais e depois nos corpos evita a substituição de corpos pelas linhas superiores.)

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

Salte para a posição do cubo.

≔§§θλμη

Busque a altura na linha e coluna atuais.

¿∨⁼±η⊕κ‹κη

Teste se um cubo deve ser desenhado nessa altura para esta linha e coluna.

¿ι“↗⊟&⁹κUhnI”___

Desenhe o corpo ou a parte superior do cubo.


Quando mudo o primeiro 3para a 33, recebo apenas 11 blocos na torre. Em geral, as torres parecem ter o limite de 11. Como isso acontece?
Fabian Röling 15/01/19

@Fabian Estou um pouco confuso que F¹¹F¹¹F¹¹não era uma pista ...
Neil

Não conheço essa linguagem de programação, apenas brinquei um pouco com o link TIO.
Fabian Röling

30

C,  376   350   313   309  285 bytes

Agradecemos a Jonathan Frech por salvar quatro 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);}

Experimente online!

Desenrolado:

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

Não pode 26*66ser 1716?
Jonathan Frech 12/01

@ JonathanFrech Claro, eu esqueci disso.
Steadybox

*s==32-> *s<33.
Jonathan Frech 12/01

for(e=k=1;e;++k)for(e=-> for(k=1;e;++k)for(e=.
Jonathan Frech 12/01

#define B b(...)&++e-> #define B++e&b(...)(assumindo bque não depende e, o que eu acho que não).
Jonathan Frech 12/01

9

JavaScript (ES6), 277251 bytes

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

Salvo 26 bytes da sugestão 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`
)

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,...'___'))))),parece salvar 26 bytes.
Neil

@Neil Brilliant! Desenhar todas as linhas superiores primeiro me poupa o trabalho de verificar se há espaços não.
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)

Experimente online!

Uma tradução em Python da abordagem de Neil's Charcoal.


É bom ver uma solução Python para isso. Minha prova de conceito do Python tinha mais de 900 bytes!
James Holderness

3
+1+k-> -~k.
Jonathan Frech 13/01

5

APL (Dyalog Unicode) , 117 116 112 bytes SBCS

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

Experimente online!


5

Tcl, 380 409 bytes

O usuário sergiol está ocupado analisando isso muito bem:

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

Experimente online!

Conteúdo 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]]]

Experimente online!

Infelizmente, é o que é. É apenas um pouco mais fácil para os olhos quando "não-destruído"

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

Constrói uma string, conforme os requisitos. Retorna a matriz do stdin. Vai de baixo para cima, da frente para trás, da direita para a esquerda sobre os dados da string. Faz isso em duas passagens, uma para a borda superior e outra para o resto do corpo de cada cubo.

Tentei torná-lo menor usando alguns lambda mojo funcionais, mas, infelizmente, isso o tornou maior.


Você pode jogar golfe: tio.run/…
sergiol

Mais golfe: tio.run/…
sergiol


Ainda mais: tio.run/…
sergiol

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.