Costruzione di blocchi 3D ASCII


82

Sfida

Scrivi un programma che accetta un array 11x11 di numeri interi e costruisce un building block 3D ASCII, in cui ciascun valore dell'array rappresenta l'altezza di una colonna di blocchi alle coordinate corrispondenti alla posizione dell'array. Un'altezza negativa è una colonna "mobile": è visibile solo il blocco superiore.

Esempio

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

Ingresso

L'input sarà un elenco di 121 numeri interi, letti dallo stdin (la scelta del separatore dipende da te) o passati come un array (può essere 1D o 2D).

Le altezze saranno comprese tra -11 e 11.

Produzione

L'edificio generato può essere scritto su stdout, visualizzato direttamente sullo schermo o restituito come stringa separata da una nuova riga.

Sono ammessi spazi iniziali e finali.

Regole di costruzione

La forma di un singolo blocco 3D è simile al seguente:

 ___
/\__\
\/__/

E un cubo di blocchi 2x2x2 si presenta così:

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

Quando i blocchi si sovrappongono, un blocco più alto ha la precedenza su uno inferiore, i blocchi davanti hanno la precedenza su quelli più indietro e i blocchi a sinistra hanno la precedenza su quelli a destra. L'unico caso speciale è che la riga superiore di un blocco non deve mai sovrascrivere alcun carattere non spaziale dietro di esso.

L'interpretazione delle altezze di colonna può essere meglio spiegata guardando una rappresentazione 2D dal lato.

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

Casi test

Se vuoi provare la tua soluzione su qualche altro input, ho messo insieme un paio di casi di test qui .

vincente

Questo è , quindi vince l'invio più breve (in byte).


9
Ohh ragazzo, preparati per soluzioni da 300+ byte. Bella sfida +1
totalmente umano il

7
@totallyhuman Nah, Dennis avrà una soluzione a 9 byte per questo in 20 minuti.
Diacono,

3
La prospettiva deve essere quella mostrata in basso a sinistra dei dati di input in primo piano? Il fatto che questo non sia il primo o l'ultimo elemento di dati rende più difficile. È accettabile 1. mantenere la mappatura così com'è e disegnare l'output con la colonna in basso a destra in primo piano o 2. disegnare un'immagine speculare o una rotazione di 90 gradi dei dati? Ognuno di questi renderebbe l'ultimo elemento di dati corrispondente alla colonna in primo piano, il che sarebbe più semplice.
Level River St

3
Sono propenso a usare un vero motore di gioco (o parte di esso) per eseguire il rendering di una foto e convertirla in ASCII
Stan Strum,

@LevelRiverSt Sembra una richiesta ragionevole: puoi scegliere l'ordine dei 121 elementi di input in modo che sia la cosa più sensata per la tua soluzione, purché l'ordine sia coerente. Deve essere possibile produrre ogni tipo di layout che può essere prodotto con l'ordine predefinito.
James Holderness,

Risposte:


25

Carbone di legna , 70 69 68 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

≔E¹¹⮌I⪪S,θ

Leggi l'array, dividi ogni riga sulle virgole e esegui il cast in numero intero, ma inverti anche ogni riga, poiché vogliamo disegnare da destra a sinistra in modo che le colonne di sinistra sovrascrivano le colonne di destra. (Altre dimensioni hanno già desiderato il comportamento di sovrascrittura.)

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

Passa attraverso i) linee superiori e corpi k) altezza l) file m) colonne. (Passare attraverso le prime linee superiori e poi i corpi evita di sovrascrivere i corpi con le linee superiori.)

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

Vai alla posizione del cubo.

≔§§θλμη

Ottieni l'altezza nella riga e nella colonna correnti.

¿∨⁼±η⊕κ‹κη

Verifica se un cubo deve essere disegnato a questa altezza per questa riga e colonna.

¿ι“↗⊟&⁹κUhnI”___

Disegna il corpo o la parte superiore del cubo.


Quando cambio il primo 3in a 33, ottengo solo 11 blocchi nella torre. In generale, le torri sembrano essere limitate alle 11. Come succede?
Fabian Röling,

@Fabian Sono leggermente confuso che F¹¹F¹¹F¹¹non era un indizio ...
Neil,

Non conosco questo linguaggio di programmazione, ho appena giocato un po 'con il collegamento TIO.
Fabian Röling,

30

C,  376   350   313   309  285 byte

Grazie a @Jonathan Frech per aver salvato quattro byte!

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

Provalo online!

srotolato:

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

Non 26*66può essere 1716?
Jonathan Frech,

@JonathanFrech Certo, me ne sono dimenticato.
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(...)(supponendo bche non dipenda da eciò che penso non lo faccia).
Jonathan Frech,

9

JavaScript (ES6), 277 251 byte

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

Salvato 26 byte dal suggerimento di @ 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,...'___'))))),sembra salvare 26 byte.
Neil,

@Neil Brilliant! Disegnare prima tutte le linee superiori mi fa risparmiare il problema di controllare i non spazi.
darrylyeo,

6

Python 2 , 243 byte

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)

Provalo online!

Una traduzione Python dell'approccio al carbone di Neil.


Bello vedere una soluzione Python golfizzata per questo. Il proof-of-concept di Python superava i 900 byte!
James Holderness,

3
+1+k-> -~k.
Jonathan Frech,

5

APL (Dyalog Unicode) , 117 116 112 byte SBCS

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

Provalo online!


5

Tcl, 380 409 byte

L'utente sergiol è stato impegnato a scrutarlo molto bene:

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

Provalo online!

Contenuto originale

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

Provalo online!

Ahimè, è quello che è. È solo un po 'più facile per gli occhi quando "ungolfed"

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

Crea una stringa, secondo i requisiti. Prende l'array dallo stdin. Va dal basso verso l'alto, dalla parte anteriore a quella posteriore, da destra a sinistra sui dati della stringa. Lo fa in due passaggi, una volta per il bordo superiore e ancora per il resto del corpo di ciascun cubo.

Ho provato a renderlo più piccolo usando qualche dolce lambda mojo funzionale, ma purtroppo lo ha ingrandito.


Puoi giocare a golf: tio.run/…
sergiol

Più golf: tio.run/…
sergiol


Ancora di più: tio.run/…
sergiol

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.